Python是一門非常流行的編程語言,擁有很多特色功能。其中,默認參數是Python函數中一個非常好用的特色功能,但許多人可能會對它的工作原理感到困惑。在本文中,我們將會從多個方面探討Python默認參數不會被修改的原因。
一、參數的默認值,只在函數被定義時求值一次
首先,Python默認參數不會被修改的原因是,參數的默認值只在函數被定義時求值一次。這就意味著,如果默認參數是可變類型(如列表或字典),並且在函數中發生了修改,那麼下一次調用該函數時,參數值將會被修改。
def f(a, L=[]):
L.append(a)
return L
print(f(1)) # [1]
print(f(2)) # [1, 2]
print(f(3)) # [1, 2, 3]
上面這個例子很好地展示了這個問題。當我們在第一次調用f函數時,L是一個空列表,輸出結果為[1]。但在之後的調用中,因為L已經包含了之前傳遞的值,所以結果會逐漸增長,輸出結果為[1, 2]和[1, 2, 3]。這就是因為L只在函數定義時求值一次導致的。
二、默認參數應該是不可變的
因此,為了避免這種情況出現,一般來說,我們應該讓默認參數是不可變類型(如字元串或整型)。如果需要使用可變類型,可以在函數內部創建一個新的可變對象,從而避免默認參數被修改的問題。
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
print(f(1)) # [1]
print(f(2)) # [2]
print(f(3)) # [3]
上面這個例子就是一個修正版本,我們使用了None來充當默認值,然後在函數內部,如果我們發現L是None類型,就新創建一個L=[]。這樣就能夠在多次調用之間避免出現參數修改問題,輸出結果是分別為[1]、[2]、[3]。
三、Python解釋器中__defaults__和__code__.co_varnames屬性的作用
理解Python默認參數不會被修改的另一個方法是更深入地了解Python解釋器中__defaults__和__code__.co_varnames屬性的作用。
def f(a, b=1, c=[]):
pass
print(f.__defaults__)
print(f.__code__.co_varnames)
上面這個例子是使用Python內置的__defaults__和__code__.co_varnames屬性,來查看函數f的默認參數和參數名稱。輸出結果分別為(1, [])和(‘a’, ‘b’, ‘c’)。這表明函數f的默認參數是從左到右排列的,並且c這個參數只在__defaults__列表中出現一次。
因此,我們可以利用這個特性來檢查默認參數是否已經被修改。查看__defaults__列表中的元素,就能夠確定默認參數是否已經被修改。如果修改了,默認參數將被替換為新列表或其他參數。
四、總結
Python默認參數不會被修改的原因是,它只在函數被定義時求值一次。如果默認參數是可變類型,且在函數內部被修改,那麼下一次調用該函數時,參數值將會被修改。為了避免這種情況,我們應該讓默認參數是不可變類型,或者在函數內部創建一個新的可變對象。通過了解Python解釋器中__defaults__和__code__.co_varnames屬性的作用,我們還可以檢查默認參數是否已經被修改。
原創文章,作者:SCRSZ,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/374688.html