Python中默认参数的作用域是什么?
当你在Python中定义一个带有数组参数的函数时,这个参数的作用范围是什么呢?
这个例子来自Python的教程:
def f(a, L=[]):
L.append(a)
return L
print f(1)
print f(2)
print f(3)
输出结果是:
[1]
[1, 2]
[1, 2, 3]
我不太确定我是否理解这里发生了什么。这是否意味着数组的作用范围在函数外面?为什么数组在每次调用时都能记住它的值?我之前用过其他语言,通常只有当变量是静态的时,才会有这样的行为。否则,我觉得每次调用时应该会重置。而实际上,当我尝试以下代码时:
def f(a):
L = []
L.append(a)
return L
我得到了我预期的结果(数组在每次调用时被重置)。
所以我觉得我只需要解释一下这一行 def f(a, L=[]):
- 变量 L
的作用范围是什么呢?
7 个回答
3
其实这里的“魔法”比你想象的还要少。这相当于
m = []
def f(a, L=m):
L.append(a)
return L
print f(1)
print f(2)
print f(3)
m
只会被创建一次。
7
你对变量 L
的作用范围理解得很对。
其实“问题”出在你用 []
创建的列表上。Python 在你每次调用这个函数的时候,并不会创建一个新的列表。每次调用时,L
都是指向同一个列表,这就是为什么这个函数会“记住”之前的调用。
所以实际上你得到的是这样的情况:
mylist = []
def f(a, L=mylist):
L.append(a)
return L
Python教程是这么说的:
默认值只会被计算一次。当默认值是一个可变对象,比如列表、字典或大多数类的实例时,这一点尤其重要。
它还建议了一种可以实现你期望行为的编码方式:
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
28
作用域就像你想的那样。
可能让人惊讶的是,默认值只计算一次,然后重复使用。所以每次你调用这个函数时,得到的都是同一个列表,而不是一个新的空列表。
这个列表存储在 f.__defaults__
中(在 Python 2 中是 f.func_defaults
)。
def f(a, L=[]):
L.append(a)
return L
print f(1)
print f(2)
print f(3)
print f.__defaults__
f.__defaults__ = (['foo'],) # Don't do this!
print f(4)
结果:
[1]
[1, 2]
[1, 2, 3]
([1, 2, 3],)
['foo', 4]