为什么exec在内部断开? [英] Why are closures broken within exec?
问题描述
在Python 2.6中,
>>> execprint(lambda:a)()in dict(a = 2),{}
2
>> trace(最近最后调用):
文件< stdin>,第1行, in< module>
< module>中的文件< string>,第1行
在< lambda>中的文件< string>,第1行。
NameError:全局名称'a'未定义
>>>全局(),{'a':2}中的execprint(lambda:a).__ closure__
无
我希望它打印两次 2
,然后打印一个带有单个单元格的元组
。在3.1中也是同样的情况。发生了什么?
当你传递一个字符串到 exec
eval
,它会将该字符串编译为代码对象,然后再考虑全局变量或局部变量。所以当你说:
eval('lambda:a',...)
这意味着:
('lambda:a','< stdin&';'eval'),...)
没有办法编译
知道 a
是一个freevar,因此将其编译为全局引用:
>>> c = compile('lambda:a','< stdin>','eval')
>>> c.co_consts [0]
< code object< lambda>在0x7f36577330a8,文件< stdin>,第1行>
>>>> dis.dis(c.co_consts [0])
1 0 LOAD_GLOBAL 0(a)
3 RETURN_VALUE
因此,为了使它工作,你必须在全局变量而不是本地变量中加入 a
。
是的,这有点狡猾。但是,这是 exec
和 eval
为你我想...他们不应该是好的。 p>
In 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
I expected it to print 2
twice, and then print a tuple with a single cell
. It is the same situation in 3.1. What's going on?
When you pass a string to exec
or eval
, it compiles that string to a code object before considering globals or locals. So when you say:
eval('lambda: a', ...)
it means:
eval(compile('lambda: a', '<stdin>', 'eval'), ...)
There's no way for compile
to know that a
is a freevar, so it compiles it to a global reference:
>>> 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
Therefore to make it work you have to put a
in the globals and not the locals.
Yeah, it's a bit dodgy. But then that's exec
and eval
for you I suppose... they're not supposed to be nice.
这篇关于为什么exec在内部断开?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!