3 回答

TA貢獻(xiàn)1848條經(jīng)驗 獲得超10個贊
正確。除非指定上下文,否則不能在具有子功能的函數(shù)中使用exec。從文檔:
如果在函數(shù)中使用了exec并且該函數(shù)包含帶有自由變量的嵌套塊,則除非exec顯式指定exec的本地名稱空間,否則編譯器將引發(fā)SyntaxError。(換句話說,“ exec obj”將是非法的,但“ ns中的exec obj”將是合法的。)
有充分的理由,如果不是星期天晚上,我可能會明白?,F(xiàn)在,下一個問題:為什么要使用exec?很少需要。你說你有充分的理由。我對此表示懷疑。;)如果您有充分的理由,我會告訴您解決方法。:-P
哦,好了,這仍然是:
def test2():
"""Test with a subfunction."""
exec 'print "hi from test2"' in globals(), locals()
def subfunction():
return True

TA貢獻(xiàn)1875條經(jīng)驗 獲得超5個贊
盡管在Python中看起來好像局部變量存儲在字典中locals()
,但通常不是。相反,它們通常存儲在堆棧中,并通過索引進(jìn)行訪問。這使得局部變量查找的速度比每次必須進(jìn)行字典查找的速度都要快。如果使用該locals()
函數(shù),則得到的是從所有局部變量創(chuàng)建的新字典,這就是為什么分配給locals()
通常不起作用的原因。
此方案有兩個例外:
當(dāng)您exec
在函數(shù)內(nèi)部使用非限定條件時,Python會關(guān)閉優(yōu)化,并使用真正的字典作為局部變量。這意味著您可以從中創(chuàng)建或更新變量exec
,但這也意味著該函數(shù)中所有本地變量訪問將運(yùn)行得更慢。
另一個例外是,當(dāng)您嵌套函數(shù)時,內(nèi)部函數(shù)可以訪問外部函數(shù)范圍內(nèi)的局部變量。執(zhí)行此操作時,變量將存儲在“單元”對象中,而不是存儲在堆棧中。無論是從內(nèi)部函數(shù)還是外部函數(shù)訪問范圍變量,額外的間接級別都會使作用域變量的使用變慢。
您遇到的問題是,通常如何存儲局部變量的這兩個例外是不兼容的。您不能將變量存儲在字典中并同時通過單元格引用進(jìn)行訪問。Python 2.x通過禁止exec來解決此問題,即使在這種情況下,您也不想使用任何作用域變量。

TA貢獻(xiàn)1780條經(jīng)驗 獲得超1個贊
這是一個很有趣的情況:
>>> def func():
... exec('print "hi from func"')
... def subfunction():
... return True
...
File "<stdin>", line 2
SyntaxError: unqualified exec is not allowed in function 'func' because
it contains a nested function with free variables
確實不起作用的原因是它subfunction包含一個自由變量,并且由于在Python 2中,exec理論上可以修改包含范圍中的局部變量,因此無法決定該變量是應(yīng)與全局變量還是與父變量綁定功能范圍。Python Zen中的其中一句詩是“面對模棱兩可,拒絕猜測的誘惑”。這就是Python 2所做的。
現(xiàn)在的問題是:這個自由(未綁定)變量是什么?好吧,是True!
實際上,它可以通過None以下方式重現(xiàn):
>>> def func():
... exec('print "hi from func"')
... def subfunction():
... return None
...
File "<stdin>", line 2
SyntaxError: unqualified exec is not allowed in function 'test2' because it contains a nested
function with free variables
即使None無法分配給它,并且在字節(jié)碼中將其視為常量,但越野車解析器仍認(rèn)為這是一個未綁定變量。
但是,如果您將其替換為1并且可以正常使用,則可以:
>>> def test2():
... exec('print "hi from func"')
... def subfunction():
... return 1
...
>>>
為避免此錯誤,請明確指定要使用的全局變量和可能的局部變量exec,例如:
>>> def test2():
... exec 'print "hi from test2"' in {}
... def subfunction():
... return None
...
>>>
在Python 3中,exec這只是一個簡單的函數(shù),沒有由解析器或字節(jié)碼編譯器專門處理。在Python 3 exec中無法重新綁定函數(shù)本地名稱,因此此SyntaxError和歧義不存在。
Python 2 vs 3兼容性的一種特殊情況是,盡管Python 2.7文檔指出:
形式exec(expr, globals)等同于exec expr in globals,而形式exec(expr, globals, locals)等同于exec expr in globals, locals。元組形式exec提供了與Python 3的兼容性,Python 3 exec是函數(shù)而不是語句。
元組形式并不總是100%兼容的,因為在處理exec帶有嵌套函數(shù)的in函數(shù)中存在一個錯誤(issue 21591);在Python 2.7.8之前,以下代碼可能引發(fā)了異常:
def func():
exec('print "hi from test2"', {})
def subfunction():
return None
這已在Python 2.7.9中修復(fù),并且不再拋出。
添加回答
舉報