Python 为什么在exec中会中断闭包?

Python 为什么在exec中会中断闭包?,python,closures,exec,Python,Closures,Exec,在Python 2.6中 >>> exec "print (lambda: a)()" in dict(a=2), {} 2 >>> exec "print (lambda: a)()" in globals(), {'a': 2} Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<string>", line

在Python 2.6中

>>> exec "print (lambda: a)()" in dict(a=2), {}
2
>>> exec "print (lambda: a)()" in globals(), {'a': 2}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
  File "<string>", line 1, in <lambda>
NameError: global name 'a' is not defined
>>> exec "print (lambda: a).__closure__" in globals(), {'a': 2}
None
dict(a=2)中的exec“print(lambda:a)(”,{ 2. >>>globals()中的exec“print(lambda:a)(”,{'a':2} 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“”,第1行,在 文件“”,第1行,在 NameError:未定义全局名称“a” >>>globals()中的exec“print(lambda:a)。__closure___; 没有一个
我希望它打印两次
2
,然后用一个
单元格打印一个元组。这与3.1中的情况相同。发生了什么?

当您将字符串传递给
exec
eval
时,它会在考虑全局或局部变量之前将该字符串编译为代码对象。所以当你说:

eval('lambda: a', ...)
这意味着:

eval(compile('lambda: a', '<stdin>', 'eval'), ...)
因此,要让它发挥作用,你必须把
a
放在全局而不是本地


是的,这有点狡猾。但我想这就是
exec
eval
对你来说。。。他们不应该很好。

+1。自从这条帖子被贴出来寻找答案以来,我每分钟都会刷新一次。多亏了你,我现在可以自由地离开电脑一段时间,出去享受阳光。谢谢!;)
>>> c= compile('lambda: a', '<stdin>', 'eval')
>>> c.co_consts[0]
<code object <lambda> at 0x7f36577330a8, file "<stdin>", line 1>
>>> dis.dis(c.co_consts[0])
  1           0 LOAD_GLOBAL              0 (a)
              3 RETURN_VALUE