可变的默认参数
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]