可變的預設引數
def foo(li=[]):
li.append(1)
print(li)
foo([2])
# Out: [2, 1]
foo([3])
# Out: [3, 1]
此程式碼的行為符合預期,但如果我們不傳遞引數怎麼辦?
foo()
# Out: [1] As expected...
foo()
# Out: [1, 1] Not as expected...
這是因為函式和方法的預設引數是在定義時而不是執行時計算的。所以我們只有一個 li
列表的例項。
解決它的方法是僅使用不可變型別作為預設引數:
def foo(li=None):
if not li:
li = []
li.append(1)
print(li)
foo()
# Out: [1]
foo()
# Out: [1]
雖然改進雖然 if not li
正確地評估為 False
,但許多其他物件也是如此,例如零長度序列。以下示例引數可能會導致意外結果:
x = []
foo(li=x)
# Out: [1]
foo(li="")
# Out: [1]
foo(li=0)
# Out: [1]
慣用的方法是直接檢查 None
物件的引數:
def foo(li=None):
if li is None:
li = []
li.append(1)
print(li)
foo()
# Out: [1]