2013-05-09 18 views
0

在以下函數中,L存儲每次調用期間的值。跨越調用在Python中更新默認參數

例如,如果我撥打f(1),L現在是[1]。當我再次調用它時,前面的L會添加新值。所以現在L是[1,1]

def f(a, L=[]): 

    L.append(a) 
    return L 

但在這個功能:

i = 5 

def f(arg=i): 

    print arg 
i = 6 

無論多少次,我調用這個函數,參數是仍然5 - 它不保持通話之間更新。

這是什麼原因沒有得到更新,但名單呢?

+1

相關:[「Python中的最小驚訝」:可變的默認參數](http://stackoverflow.com/q/1132941/4279) – jfs 2013-05-09 01:29:23

回答

3

這是一個很好的問題。發生這種情況的原因是因爲函數的默認參數作爲單個對象存儲在內存中,每次調用該函數時都不會重新創建。

因此,當您將一個列表[]作爲默認參數時,在該程序期間將永遠只有一個列表。所以當你添加到列表中時,你將添加到列表的一個副本中。對於像5這樣的數字,這仍然是正確的。然而,數字在Python中是不可變的,所以當你改變一個以數字開始的默認參數時,你實際上是指向一個新的數字,而不是編輯該對象,而列表上的許多操作會將該列表改變成適當的位置而不是返回一個新的列表。

http://docs.python.org/3/tutorial/controlflow.html#default-argument-values

重要警告:默認值只計算一次。當默認值是可變對象(如 列表,字典或大多數類的實例)時,此 會有所不同。

推薦的解決方案,如果你需要一個空列表默認​​參數的行爲,而無需每次調用​​具有相同空列表默認​​參數的功能,就是要做到這一點:

def f(a, L = None): 

    if L is None: 
     L = [] 
    L.append(a) 
    return L 

的創建現在評估一個空列表的單個調用函數 - 不是一次。

1

a.append()不同於i = 6。第一個更改數組,但數組保持相同的對象(相同但不相等)。另一方面,後者爲變量賦予一個全新的值。它不會改變任何對象(整數不能改變)。