Python 默认参数评估

Python Default Arguments Evaluation

我正在阅读 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

如果第一个函数 fun1() 中的 L=[] 只被调用一次,那么 fun1() 的输出是好的。但是为什么 L=None 每次都在 fun2() 中被调用。

默认参数只计算一次。在 fun1 中,您有相同的列表,您一直在添加。在 fun2 中,您将新的 [] 分配给参数,然后附加到它。与任何赋值一样,其范围将限于它所在的块。

当您定义一个函数时,默认参数的值会被计算,但是函数的主体只会被编译。您可以通过属性检查函数定义的结果。有一个包含默认值的 __defaults__ 属性和包含主体的 __code__ 属性(因此这些是在定义函数时创建的)。

第二个示例中发生的事情是 None 确实在定义时得到了评估(它评估为 None duh!),但是有条件地将 [] 分配给 L 只被编译并且每次都是 运行(条件通过)。

函数声明中的

L=[] 使 Python 本质上是这样做的:

  • 此函数有一个名为 L
  • 的参数
  • 它的默认参数是[],让我们把这个特殊的[]放在一边,并在没有为L
  • 传递参数的任何时候使用它
  • 每次调用该函数时,创建一个变量L,并将传递的参数或我们之前预留的值赋给它

所以,[] 部分被执行了一次,它创建了一个列表对象,它被放在一边并保留着,这就是为什么如果你修改它它会累积变化。 None 也发生了完全相同的事情,但是 None 没有被修改,也不是可变的,所以你没有看到任何奇怪的副作用。 None 仍然只是 "executed" 一次,那个特定的 None 值被搁置,就像列表一样,只是你没有对 None 做任何事情价值本身。