預設引數的坑
定義一個函式,傳入一個list,新增一個end再返回
def add_end(L=[]): L.append('END') return L
正常呼叫時,結果似乎不錯
print add_end([1,2,3]) #[1, 2, 3, 'END']
使用預設引數呼叫時,一開始結果也是對的,但是再次呼叫時,結果就不對了
print add_end() #['END'] print add_end() #['END', 'END'] print add_end() #['END', 'END', 'END']
從上述呼叫結果發現,函式每次都記住了上次新增了‘END’後的list,python函式在定義的時候,預設引數L的值就被計算出來了即[],因為預設引數L也是一個變數,它指向物件[],每次呼叫該函式,如果改變 了L的內容,則下次呼叫時,預設引數的內容就變了,不再是函式定義時的[]了
所以,定義預設引數要牢記一點:預設引數必須指向不變物件
修改上面的例子,可以用None這個不變物件來實現
def add_end2(L=None): if L is None: L=[] L.append('END') return L
無論呼叫多少次都沒問題
print add_end2() print add_end2() print add_end2() #['END'] #['END'] #['END']
不變物件一旦建立,物件內部的資料就不能修改,這樣就減少了由於修改資料導致的錯誤。此外,由於物件不變,多工環境下同時讀取物件不需要加鎖,同時讀一點問題都沒有。我們在編寫程式時,如果可以設計一個不變物件,那就儘量設計成不變物件。
不可變(immutable):int、字串(string)、float、(數值型number)、元組(tuple)
可變(mutable):字典型(dictionary)、列表型(list)