以下代码片段从Python 2.7和3.3获得不同的输出。
data = {'_out':[1,2,3,3,4]}
codes = ['_tmp=[]',
'[_tmp.append(x) for x in _out if x not in _tmp]',
'print(_tmp)']
for c in codes:
exec(c,{},data)
Python 2.7的输出:
[1,2,3,4]
Python 3.3的输出:
Traceback (most recent call last):
File "test.py", line 8, in <module>
exec(c,{},data)
File "<string>", line 1, in <module>
File "<string>", line 1, in <listcomp>
NameError: global name '_tmp' is not defined
要修复Python 3.3中的错误,我只需将全局变量设置为与本地变量相同,即exec(c,data,data)
。知道为什么Python 3.3不像2.7那样表现吗?
答案 0 :(得分:2)
似乎已知并且期望的行为,请参阅问题13557 https://bugs.python.org/issue13557
进一步
https://docs.python.org/3/reference/executionmodel.html#interaction-with-dynamic-features
eval()和exec()函数无权访问用于解析名称的完整环境。可以在调用者的本地和全局名称空间中解析名称。 自由变量不会在最近的封闭命名空间中解析,而是在全局命名空间中解析。
您可以通过不使用列表理解和局部变量方法调用,或通过全局范围提供变量来解决上述问题
data = {'_out':[1,2,3,3,4]}
codes = ['_tmp=[]', """
for x in _out:
if x not in _tmp:
_tmp.append(x)
""",
'print(_tmp)']
for c in codes:
exec(c, {}, data)
data = {'_out':[1,2,3,3,4]}
codes = ['_tmp=[]',
'[_tmp.append(x) for x in _out if x not in _tmp]',
'print(_tmp)']
for c in codes:
exec(c, data)