有网友问
>>> def foo(bar=[]):
... bar.append("baz")
... return bar
>>> foo()
["baz"]
>>> foo()
["baz", "baz"]
>>> foo()
["baz", "baz", "baz"]
为什么多次调用foo()bar的值不会重新赋值为[]呢?bar的作用域不是应该在foo函数之内吗?
文档中是这么说的。
Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:
重要警告:默认值只计算一次。当默认值是可变对象(如列表,字典或大多数类的实例)时,这会有所不同。例如,以下函数会累积在后续调用中传递给它的参数
例子一:
i = 5
def f(arg=i):
print(arg)
i = 6
f()
输出值为5,不是6
例子二:
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
输出值为
[1]
[1, 2]
[1, 2, 3]
这个原因是由于默认参数只计算一次,因为list 是可变数据类型,函数每次调用时,L 是同一个对象的引用。
加一个id(),可以判断每次函数的调用都是访问的同一个list 实例对象。
def f(a, L=[]):
L.append(a)
print(id(L))
return L
print(f(1))
print(f(2))
print(f(3))
怎么破解这个问题,这样去修改代码。
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L