Python 2.X中的以下代码按照您的预期打印“a:2”:
def f():
#a = 1
exec "a = 2" in globals(), locals()
for k,v in locals().items(): print k,":",v
#a = 3
f()
但如果你取消注释“a = 1”,那么就会打印出“a:1”,正如我没想到的那样。 甚至更奇怪,如果你取消注释“a = 3”线,那么它根本不打印任何东西,我绝对没想到(我有一个令人困惑的错误,我提炼到那个)。
我认为答案隐藏在locals()和globals()的文档中,或者可能在其他问题like this中,但我认为值得将此表现出来。
我很想知道Python解释器在这里想到的是什么,以及解决方法的建议。
答案 0 :(得分:2)
旧的Python 2 exec
会更改字节码以搜索本地名称空间和全局名称空间。
当您在全局中定义a = 2
时,这是在a = 1
被评论时找到的那个。取消注释a = 3
后,这是a
“找到”但尚未定义。
如果您阅读了如何在此great article by Eli Bendersky中处理符号表,您可以更好地了解如何处理局部变量。
您不应该将exec
用于此类代码(我希望这不是生产代码),并且当您将代码移植到Py3k时它会中断:
Python 3的exec
函数不再是一个语句,因此无法改变它所处的环境。
可能我应该直截了当地说:
如果你正在做所有这些动态命名的东西,你应该使用字典:
def f():
data = {'a': 1}
data['a'] = 2
if ...:
data['a'] = 3