I have a variable, abc
, defined as 'batting_stats'
and want to run a line of code that is 'pyb.batting_stats(2020)'
. I want to use string syntax to create the line by joining abc with 'pyb.'
and '(2020)'
and then run that line of code - how can I do this? I seem to be creating a larger string instance rather than a runnable line of code. Cheers!

- 45
- 3
-
1Does this answer your question? [How do I execute a string containing Python code in Python?](https://stackoverflow.com/questions/701802/how-do-i-execute-a-string-containing-python-code-in-python) – wjandrea Oct 10 '21 at 03:35
-
1Or maybe this would be better: [How to access object attribute given string corresponding to name of that attribute](/q/2612610/4518341) – wjandrea Oct 10 '21 at 03:58
1 Answers
You probably don't want to do this; it's possible, but in the vast majority of circumstances, it's a bad idea.
Options:
If possible, try to rewrite the code so you don't need to look up by name at all; for instance, you could change the other code so that it stores
pyb.batting_stats
as a function rather than as a stringabc = pyb.batting_stats # note no brackets # later result = abc(2020)
If you do need to look up by name, you can use
getattr
, like this:# At the top of the script ALLOWED_NAMES = ['batting_stats', ...] # in the code where you need it if abc not in ALLOWED_NAMES: raise ValueError("Invalid name passed: %s" % abc) result = getattr(pyb, abc)(2020)
Probably a better way would be to use a dictionary as a dispatch table:
dispatch_table = { 'batting_stats': pyb.batting_stats, ...: ..., } result = dispatch_table[abc](2020)
This automatically raises an exception if an unexpected name is passed.
It also has the benefit that you can use a different string in the
abc
variable than the method name; for example, if you need to rename the function but maintain the names in an API or vice versa:dispatch_table = { 'battingstats': pyb.batting_stats, # legacy name 'batting_stats': pyb.batting_stats, ...: ..., } result = dispatch_table[abc](2020)
If you absolutely must run a piece of code from a string, you can use the
eval
orexec
builtin functions; however, it's almost always a bad idea.Use of
eval
andexec
is so frequently dangerous and insecure (Common Weakness #95) that it's better to avoid it altogether. Luckily, at least in Python, there's almost always an alternative; moreover, those alternatives are typically cleaner, more flexible, faster to run and easier to debug. Cases where there's no alternative are vanishingly rare.

- 6,697
- 2
- 17
- 17
-
Thanks that is really helpful! At the top of the comment when you said "You probably don't want to do this; it's possible, but in the vast majority of circumstances, it's a bad idea." was that specifically in reference to the 'eval' and 'exec' code? In general, if I wanted to standardize running methods with certain parameters and wanted to change only the method name (string), what would be the best practice here? Cheers! Really appreciate your help – David Oct 12 '21 at 20:38
-
Or rather, being new to coding, what is the best practice for standardizing running the line of code `pyb.XYZ(2020)` where XYZ changes each time run? Thanks again for the guidance – David Oct 12 '21 at 20:47
-
Best practice would probably be the "dispatch table" option, either written explicitly (like Django routes) or via decorators on each of the methods that may be run (like Flask routes) – Jiří Baum Oct 12 '21 at 22:10
-
I'm assuming that you're getting the method name because you're serving some sort of API; if it's coming from within the same program, probably better not to use a string at all – Jiří Baum Oct 12 '21 at 22:13
-
Thanks, it is actually not for an API (I am not sure what that is.) The use is for an internal program where pyb has different 'methods' (I think that's the name) that I want to call, and all with the same specifications. Basically pyb.batting_stats(2020) and a series of code after, then pyb.XXXX(2020) with the same series of code afterward to format. – David Oct 17 '21 at 20:33
-
In that case, don't use a string; just put the method itself in a variable, or otherwise rearrange it so you don't need to use a string – Jiří Baum Oct 17 '21 at 20:58
-
Ok that is super helpful, thank you so much! One other question, what if I want to create variables based on the input dictionary. So for example if the dictionary contains methods that produce a dataframe, I modify the dataframe, and then want to name and have part of the original variable name can that be done? To use the above example, it could be a variable called 'battingstatsMOD' which is based off the 'battingstats' key in the dictionary. I am not sure how to avoid using a string here to create the new variable name. – David Oct 19 '21 at 17:59
-
Why not put it in a new dictionary? `modified['battingstats'] = ...` – Jiří Baum Oct 20 '21 at 01:24
-
Hmm, I'm not sure I see how that would work. Basically if the input dictionary contains {'xyz': corresponding method, etc} and I then want to create a variable output called xyz1, I could manipulate the 'xyz' string although then would not be sure how to define a variable based on that. – David Oct 22 '21 at 23:57
-
Instead of putting it in a variable called `xyz1`, put it in `results['xyz']`; creating local variables based on a string is usually a bad idea – Jiří Baum Oct 23 '21 at 06:32
-
Ok got it. For a different example, if I have a function that takes a dataframe as input `pyth_wins(df)` and I want the name of the dataframe to create a new variable `total_DF` where DF references the original input name how would you do that? So basically total_ & the string of the input (name of that dataframe). This variable would equal a sum function applied to the dataframe after some manipulation. If I wanted to run `pyth_wins(2020)` it would create variable `total_2020` and if `pyth_wins(2021)`, `total_2021`. This would also be an output of the function, so reference able later on – David Oct 23 '21 at 23:28
-
-
Right, but the key to the dataframe would be a string. So if I wanted to manipulate it and add to the end, then use that to create a new variable, can that be done? Not sure I am articulating this well at all, so please let me know if I am not being clear. – David Oct 24 '21 at 20:32
-
Just keep using dictionaries (or similar) for the rest of the program – Jiří Baum Oct 25 '21 at 21:08