2.2.2 默认参数
Python 的函数可以有默认值,这个功能很好用:
def foo(a, l=[]):
l.append(a)
return l
foo(2,[1]) # 给数组 [1] 添加一个元素 2,得到 [1,2]
foo(2) # 没有传入数组,使用默认的空数组,得到 [2]
然而如果这样调用:
foo(2) # 利用默认参数,得到 [2]
foo(3) # 竟然得到了 [2, 3]
函数调用了两次以后,默认参数被改变了,也就是说函数调用产生了副作用。这是因为默认参数的存储并不像函数里的临时变量一样存储在栈上、随着函数调用结束而释放,而是存储在函数这个对象的内部:
foo.__defaults__ # 一开始确实是空数组
foo(2) # 利用默认参数,得到 [2]
foo.__defaults__ # 如果打印出来看,已经变成 [2] 了
foo(3) # 再添加一个元素就得到了 [2, 3]
因为函数 foo
作为一个对象,不会被释放,因此这个对象内部的属性也不会随着多次调用而自动重置,会一直保持上次发生的变化。基于这个前提,我们得出一个结论:函数的默认参数不允许是可变对象,比如这里的 foo
函数需要这么写:
def foo(a, l=None):
if l is None:
l = []
l.append(a)
return l
print(foo(2)) # 得到 [2]
print(foo(3)) # 得到 [3]
现在,给参数添加默认值的行为在函数体中完成,不会随着函数的多次调用而累积。
对于 Python 的默认参数来说:
如果默认值是不可变的,可以直接设置默认值,否则要设置为 None 并在函数体中设置默认值。
Last updated