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.