黄哥Python Python 参数默认参数之值只计算一次

有网友问

>>> 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

黄哥谈转行当程序员
黄哥谈转行当程序员之二