def foo(li=[]): li.append(1) print(li) foo([2]) # 出:[2,1] foo([3]) # 出:[3,1]
该代码的行为符合预期,但是如果我们不传递参数怎么办?
foo() # 出:[1]符合预期... foo() # 出:[1,1]与预期不符...
这是因为函数和方法的默认参数是在定义时而不是运行时求值的。因此,我们只有一个li列表实例。
解决方法是对默认参数仅使用不可变类型:
def foo(li=None): if not li: li = [] li.append(1) print(li) foo() # 出:[1] foo() # 出:[1]
尽管改进并且可以if not li正确评估为False,但许多其他对象也可以这样做,例如零长度序列。以下示例参数可能会导致意外的结果:
x = [] foo(li=x) # 出:[1] foo(li="") # 出:[1] foo(li=0) # 出:[1]
惯用的方法是直接检查None对象的参数:
def foo(li=None): if li is None: li = [] li.append(1) print(li) foo() # 出:[1]