赋值顺序意外地与"globals(),locals()中的exec expr"有关.

dre*_*ves 7 python eval global-variables

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()
Run Code Online (Sandbox Code Playgroud)

但如果你取消注释"a = 1",那么就会打印出"a:1",正如我没想到的那样.甚至更奇怪,如果你取消注释"a = 3"线然后它根本不打印任何东西,我绝对没想到(我有一个令人困惑的错误,我提炼到那个).

我认为答案隐藏在locals()和globals()的文档中,或者可能在其他类似的问题中,但我认为值得称之为这种表现形式.

我很想知道Python解释器在这里想到的是什么,以及解决方法的建议.

JBe*_*rdo 2

旧的 Python 2exec会更改字节码以搜索本地和全局命名空间。

当您在全局中定义 时,这是在注释a = 2时找到的。a = 1当您取消注释时a = 3,这是a“找到的”但尚未定义。

如果您阅读Eli Bendersky 撰写的这篇精彩文章中的符号表是如何处理的,您可以更好地理解局部变量是如何处理的。

您不应该使用exec这种代码(我希望这不是生产代码),并且当您将代码移植到 Py3k 时它无论如何都会中断:

Python 3 的exec函数不再是一个语句,因此无法改变它所在的环境。


也许我应该直接进入正题:

如果你正在做所有这些动态命名的事情,你应该使用字典:

def f():
    data = {'a': 1}
    data['a'] = 2
    if ...:
        data['a'] = 3
Run Code Online (Sandbox Code Playgroud)

  • @dreeves 使用字典代替:`data = {'a': 1}; 数据['a'] = 2` (3认同)