Python exec behaves differently between 2.7 and 3.3

Below, the code snippet gets different results from Python 2.7 and 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)

Exiting Python 2.7:

[1,2,3,4]

Exiting 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

To correct the error in Python 3.3, I just set global variables as the same as the locals, that is exec(c,data,data). Any idea why Python 3.3 doesn't behave like 2.7?

+4
source share
1 answer

As you know, behavior is desirable , see question 13557 https://bugs.python.org/issue13557

and further in

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)
+2

Source: https://habr.com/ru/post/1623003/


All Articles