我正在阅读Python Documentation Release 2.7.10中的python教程,我发现了类似的内容。
代码
def fun1(a,L=[]):
L.append(a)
return L
print fun1(1)
print fun1(2)
print fun1(3)
def fun2(a,L = None):
if L is None:
L=[]
L.append(a)
return L
print fun2(1)
print fun2(2)
print fun2(3)
输出
[1]
[1, 2]
[1, 2, 3]
[1]
[2]
[3]
Process finished with exit code 0
如果第一个函数L=[]
中的fun1()
仅被调用一次,则fun1()
的输出就可以了。但是,为什么每次L=None
都会调用fun2()
。
答案 0 :(得分:2)
L=[]
使Python基本上这样做:
L
[]
,让我们将此特定[]
放在一边,并在L
L
,并为其分配传递的参数或我们之前预留的值因此,[]
部分将被执行一次,这将创建一个列表对象,该列表对象被搁置并保留,这就是为什么它会在您修改它时累积更改的原因。 None
完全相同,但None
未被修改,也不可变,因此您没有看到任何奇怪的副作用。 None
仍然只被“执行”一次,并且就像列表一样,这个特定的None
值被放在一边,只是你没有对None
值本身做任何事情
答案 1 :(得分:1)
默认参数仅评估一次。在fun1
中,您将添加相同的列表。在fun2
中,您为参数指定了新的[]
,然后附加到该参数。与任何赋值一样,其范围将仅限于它发生的块。
答案 2 :(得分:1)
定义函数时,会计算默认参数的值,但只会编译函数体。您可以通过属性检查函数定义的结果。 Theres __defaults__
属性包含默认值和包含正文的__code__
属性(因此在定义函数时会创建这些属性)。
第二个示例中发生的是None
在定义时进行评估(评估为None
duh!),但有条件地将[]
分配给的代码L
只会被编译并且每次都会运行(条件通过)。