2012-09-09 16 views
11

嵌套範圍需要從PEP 227理解下面的句子幫助和例子Python Language ReferencePython的動態特性

If a variable is referenced in an enclosed scope, it is an error to delete the name. The compiler will raise a SyntaxError for 'del name'.

缺乏造成我無法在編譯時重現錯誤,所以用一個例子解釋是高度可取的。

回答

15

下引發execption:

def foo(): 
    spam = 'eggs' 
    def bar(): 
     print spam 
    del spam 

因爲spam變量在的bar封閉範圍被使用:

>>> def foo(): 
...  spam = 'eggs' 
...  def bar(): 
...   print spam 
...  del spam 
... 
SyntaxError: can not delete variable 'spam' referenced in nested scope 

的Python檢測spam被引用在bar但不分配任何東西給這個變量,所以它在foo的周圍範圍內查找它。它分配在那裏,使del spam語句出現語法錯誤。

這個限制在Python 3.2中被刪除;您現在負責自己不刪除嵌套變量;你會得到一個運行時錯誤(NameError)代替:

>>> def foo(): 
...  spam = 'eggs' 
...  def bar(): 
...   print(spam) 
...  del spam 
...  bar() 
... 
>>> foo() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 6, in foo 
    File "<stdin>", line 4, in bar 
NameError: free variable 'spam' referenced before assignment in enclosing scope 
4

一個例子可以是這樣:

>>> def outer(): 
...  x = 0 
...  y = (x for i in range(10)) 
...  del x 
... 
SyntaxError: can not delete variable 'x' referenced in nested scope 

基本上就意味着你不能刪除在內部塊中使用的變量(以這種情況下genexp)。

請注意,這適用於python < = 2.7.x和python < 3.2。 在python3.2這是它不會引發語法錯誤:

>>> def outer(): 
...  x = 0 
...  y = (x for i in range(10)) 
...  del x 
... 
>>> 

this鏈接變化的整個故事。

我覺得python3.2 semanthics是比較正確的,因爲如果你寫的代碼相同的功能外它的工作原理:

#python2.7 
>>> x = 0 
>>> y = (x for i in range(10)) 
>>> del x 
>>> y.next()  #this is what I'd expect: NameError at Runtime 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 1, in <genexpr> 
NameError: global name 'x' is not defined 

,而把同樣的代碼放到一個函數,不僅改變了異常,但錯誤正在編譯時。