Python坑之——預設引數必須指向不變物件
阿新 • • 發佈:2019-02-10
先定義一個函式,傳入一個list,新增一個END
再返回:
def add_end(L=[]):
L.append('END')
return L
當你正常呼叫時,結果似乎不錯:
>>> add_end([1, 2, 3])
[1, 2, 3, 'END']
>>> add_end(['x', 'y', 'z'])
['x', 'y', 'z', 'END']
當你使用預設引數呼叫時,一開始結果也是對的:
>>> add_end()
['END']
但是,再次呼叫add_end()
時,結果就不對了:
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
預設引數是[]
,但是函式似乎每次都“記住了”上次添加了'END'
後的list。
原因解釋如下:
Python函式在定義的時候,預設引數L的值就被計算出來了,即[]
,因為預設引數L
也是一個變數,它指向物件[]
,每次呼叫該函式,如果改變了L
的內容,則下次呼叫時,預設引數的內容就變了,不再是函式定義時的[]
了。
所以,定義預設引數要牢記一點:預設引數必須指向不變物件!
要修改上面的例子,我們可以用None
這個不變物件來實現:
def add_end (L=None):
if L is None:
L = []
L.append('END')
return L
現在,無論呼叫多少次,都不會有問題:
>>> add_end()
['END']
>>> add_end()
['END']