In Python 2.7 I used to be able to use the following code (I'm using the emcee package):
def main():
from emcee import moves
emcee_moves = ['KDEMove(),0.5', 'DEMove(),0.5']
mv = [(eval("moves." + _)) for _ in emcee_moves]
if __name__ == '__main__':
main()
I use this because I feed the "moves" through an input parameters file (this is a little portion of a much larger code), which means they are read as strings. In Python 3.x this now throws:
*** NameError: name 'moves' is not defined
This is apparently related to this wont fix bug as mentioned in this old question: Eval scope in Python 2 vs. 3 .
I've also read that using eval()
is generally discouraged. My question is then: how do I replicate the above code which used to work in Python 2.7?
Edit
This is the actual code that fails. It need to be inside a function, otherwise it won't fail.
As Pete said, your example works for python 3.6.8. However, another way of doing what you want is:
from emcee import moves
emcee_moves = [('KDEMove', 0.5), ('DEMove', 0.5)]
mv = [(getattr(moves, method)(), val) for method, val in emcee_moves]
getattr is generally safer than eval.
You can always replace the list comprehension with a regular loop. Less fancy, but gives the same functionality.
Although I have Python 3.8.0 and the code works as expected - without any errors.
, as my comment says, it's still possible to do these without any eval()
.
You want to dynamically get a class from a module. You can use getattr()
for this.
from emcee import moves
emcee_moves = ['KDEMove', 'DEMove']
mv = [getattr(moves, _)() for _ in emcee_moves]
Output:
In [22]: mv = [getattr(moves, _)() for _ in emcee_moves]
In [23]: mv
Out[23]:
[<emcee.moves.kde.KDEMove at 0x7f2bf8b98a90>,
<emcee.moves.de.DEMove at 0x7f2bf90b08e0>]
I'm not exactly sure why those ,0.5
suffixes were there ( __init__
arguments, maybe?) , but the "gist of it" is written above.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.