2012-11-24 22 views
2
>>> x = [] 
>>> y = [1,2,3] 
>>> def func1(L): 
...  x+=L 
... 
>>> def func2(L): 
...  x.extend(L) 
... 
>>> func1(y) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in func1 
UnboundLocalError: local variable 'x' referenced before assignment 
>>> func2(y) 
>>> x 
[1, 2, 3] 

爲什麼列表extend()方法會改變非全局變量,但+ =運算符不能?據我所知,只要函數不分配變量,它就可以在沒有全局名稱的情況下讀取它。但在這種情況下,函數確實設置了值。python - 爲什麼可以擴展修改一個沒有全局名稱的值?

回答

5

它不設置該值,它會修改現有值。在Python中,將名稱綁定到值是一回事,修改(或變異)值是另一回事。

真正的問題是爲什麼+=沒有工作,因爲對於列表,這個操作被定義爲也就地修改列表。答案就是這樣,因爲那個運算符看起來像是賦值,所以決定讓它像分配用於範圍和綁定目的一樣。 The documentation說(強調):

增強分配評估目標(它不同於正常的賦值語句,不能是拆包)和表達式列表,執行特定於該類型分配的二進制運算兩個操作數,並且將結果分配給原始目標

換句話說,增強賦值包含賦值作爲操作的一部分,所以正常的作用域/綁定規則適用。由於目標被評價爲一個目標,如果它是它當作一個局部變量的函數。所以,當x是一個列表,x += newList實際上是這樣的:

x.extend(newList) 
x = x 

更一般地,增量賦值可以修改就地操作數,但它仍然然後嘗試所產生的價值重新綁定到原始變量。所以x += other作品基本上是這樣的:

y = x.__iadd__(other) 
x = y 
相關問題