cha*_*lie 25 python parameters scope function-calls default-value
当您使用数组参数在Python中定义函数时,该参数的范围是什么?
这个例子来自Python教程:
def f(a, L=[]):
L.append(a)
return L
print f(1)
print f(2)
print f(3)
Run Code Online (Sandbox Code Playgroud)
打印:
[1]
[1, 2]
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
我不太确定我是否理解这里发生的事情.这是否意味着数组的范围超出了函数的范围?为什么数组会记住从调用到调用的值?来自其他语言,只有当变量是静态的时候我才会期望这种行为.否则它似乎应该每次重置.实际上,当我尝试以下内容时:
def f(a):
L = []
L.append(a)
return L
Run Code Online (Sandbox Code Playgroud)
我得到了我期望的行为(每次调用都重置了数组).
所以在我看来,我只需要def f(a, L=[]):解释这一行- L变量的范围是什么?
Mar*_*ers 23
范围如您所料.
可能令人惊讶的是,默认值只计算一次并重复使用,因此每次调用函数时都会得到相同的列表,而不是初始化为[]的新列表.
该列表存储在f.func_defaults.
def f(a, L=[]):
L.append(a)
return L
print f(1)
print f(2)
print f(3)
print f.func_defaults
f.func_defaults = (['foo'],) # Don't do this!
print f(4)
Run Code Online (Sandbox Code Playgroud)
结果:
[1]
[1, 2]
[1, 2, 3]
([1, 2, 3],)
['foo', 4]
Run Code Online (Sandbox Code Playgroud)
L变量的范围符合您的预期.
"问题"与您正在创建的列表有关[].每次调用函数时,Python都不会创建新列表. L每次调用时都会分配相同的列表,这就是函数"记住"之前调用的原因.
所以实际上这就是你所拥有的:
mylist = []
def f(a, L=mylist):
L.append(a)
return L
Run Code Online (Sandbox Code Playgroud)
默认值仅计算一次.当默认值是可变对象(如列表,字典或大多数类的实例)时,这会有所不同.
并建议以下方式来编码预期的行为:
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
Run Code Online (Sandbox Code Playgroud)