2012-02-08 27 views
3

尋找此代碼爲什麼會提高的良好解釋SyntaxErrorexec的行爲的任何解釋?

def echo(x): 
    return x 

def foo(s): 
    d = {} 
    exec(s, {}, d) 
    return dict((x,y) for x,y in d.items()) 

def bar(s): 
    d = {} 
    exec(s, {}, d) 
    return dict((x, echo(y)) for x,y in d.items()) # comment this to compile 

s = 'a=1' 
foo(s) 

File "test.py", line 11 
    exec(s, {}, d) 
SyntaxError: unqualified exec is not allowed in function 'bar' it contains a 
      nested function with free variables 
+6

這究竟應該怎麼辦? – 2012-02-08 14:35:34

+3

@DanielRoseman:實際的問題似乎是:爲什麼'foo()'是有效的Python而bar()不是?在我看來,這是一個非常有效的問題,儘管應該說清楚一點。 – 2012-02-08 14:40:49

+1

@DanielRoseman:D此代碼僅供解釋。真正的代碼是更可接受的版本。我只是在尋找高管的解釋。 – Shekhar 2012-02-08 14:42:14

回答

7

在Python 2.x中,exec報表可能不會出現具有本地 「功能」 與自由變量函數內。生成器表達式隱式地定義了應該在每次迭代中執行的代碼的某種「函數」(或更確切地說,代碼對象)。在foo()中,此代碼僅包含對xy的引用,這些引用是生成器表達式內的本地名稱。在bar()中,該代碼還包含對自由變量echo的引用,因此bar()不適合使用exec

另外請注意,您的exec語句可能應該讀

exec s in {}, d 

這將他們變成合格 EXEC語句,使代碼有效。

請注意,您的代碼可以在Python 3.x中工作。 exec()已經變成了函數,並且不能再修改封閉函數的局部變量,從而使得上述對於使用exec的限制是不必要的。

+0

完美。和python 3.x提示+1。 – Shekhar 2012-02-08 14:52:45

+1

@Shekhar:添加了一個重要的細節... – 2012-02-08 14:56:00

+0

謝謝。還注意到'exec in ..'只適用於2.x. – Shekhar 2012-02-08 15:00:32

3

您可能會嘗試使用python 3.x手冊編寫python 2.x代碼。對於Python 3.2,我不會得到這個錯誤,在Python 2.7中exec的語法是quite different