小心Python中的可变默认参数

在Python中,默认参数只会被评估一次。评估发生在函数定义时,而不是每次调用函数时。如果你使用可变的默认参数并在某个时刻对其进行了修改,这可能会无意中创建隐藏的共享状态。这意味着被修改的参数也成为了以后所有对该函数的调用的默认值。

以以下代码为例。每次调用函数时都共享同一个列表。因此,第二次调用时,函数不会从空列表开始。相反,默认参数是包含前一次调用值的列表。

def append(n, l = []):
  l.append(n)
  return l

append(0) # [0]
append(1) # [0, 1]

如果你确实需要在函数中使用可变对象作为默认值,你可以将参数的默认值设置为None。然后,在函数体中检查它是否为None,如果是,你可以将其设置为你想要的可变值,而不会产生副作用。

def append(n, l = None):
  if l is None:
    l = []
  l.append(n)
  return l

append(0) # [0]
append(1) # [1]