過去遇到毛毛蟲總是會想著「為什麼」這個要出現毛毛蟲,而這一次出現毛毛蟲也同樣想了這個「為什麼」,而且覺得比較特別,所以就把他筆記一下w
先來寫了以下這段 code
def add_something_to_array(element, array=[]):
array.append(element)
return array
my_array_a = add_something_to_array("a")
print(my_array_a)
結果也會很簡單的回覆給我 ['a']
但是
如果第二次呼叫他的時候,問題就會出現了
把 code 先改成以下的樣子
def add_something_to_array(element, array=[]):
array.append(element)
return array
my_array_a = add_something_to_array("a")
print(my_array_a)
my_array_b = add_something_to_array("b")
print(my_array_a)
print(my_array_b)
來看看執行的結果
就會發現到裡面這個 array,會被外部重複使用,原因是什麼呢?
Python 在定義 function 的預設參數時,只會被定義一次,而不是在每次呼叫的時候重新定義一次,所以上面這一小段 code: array = [] 才會一直被重複使用。
那該怎麼做呢?
你應該要避免在預設的參數裡面設定一個可變動的變數,將可變動的預設參數改為 None,在程式碼裡面判斷並賦予原本預設的可變動變數,如下
def add_something_to_array(element, array=None):
if array is None:
array=[]
array.append(element)
return array
my_array_a = add_something_to_array("a")
print(my_array_a)
my_array_b = add_something_to_array("b")
print(my_array_a)
print(my_array_b)
當初在 code review 的時候遇到這樣寫法,還以為是在炫技,抱歉是我錯了
執行結果如下,這樣一切就會跟我們預想的結果相同啦!
感謝網友陳信宏補充,使用 frozenset() 也能夠避免此 code lint 警告
def aa(a, b=frozenset()):
return [*b, a]
print(aa("1"))
# ['1']
print(aa("2", frozenset(["a", "v"])))
# ['v', 'a', '2']