我正在阅读 Python 文档版本 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()
。
L=[]
使得Python本质上是这样做的:
L
[]
,让我们将这个特定的 []
放在一边,并在没有为 L
L
,并将传递的参数或我们之前预留的值分配给它因此,
[]
部分被执行一次,这会创建一个列表对象,该对象被搁置并保留,这就是为什么如果您修改它,它会累积更改。与 None
发生完全相同的事情,但是 None
没有被修改,也不是可变的,所以你不会看到任何奇怪的副作用。 None
仍然只被“执行”一次,并且特定的 None
值就像列表一样被保留,只是您没有对 None
值本身做任何事情。
定义函数时,将计算默认参数的值,但仅编译函数体。您可以通过属性检查函数定义的结果。有一个包含默认值的
__defaults__
属性和包含主体的 __code__
属性(因此这些是在定义函数时创建的)。
第二个示例中发生的情况是
None
确实在定义时被求值(它的求值结果为 None
啊!),但是有条件地将 []
分配给 L
的代码每次都会被编译并运行(条件通过)。
默认参数仅计算一次。在
fun1
中,您有不断添加的相同列表。在 fun2
中,您将新的 []
分配给参数,然后附加到它。与任何赋值一样,其范围将仅限于它发生的块。