Python 默认参数评估[重复]

问题描述 投票:0回答:3

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

python arguments default-arguments
3个回答
4
投票
函数声明中的

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

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

因此,

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


2
投票

定义函数时,将计算默认参数的值,仅编译函数体。您可以通过属性检查函数定义的结果。有一个包含默认值的

__defaults__
属性和包含主体的
__code__
属性(因此这些是在定义函数时创建的)。

第二个示例中发生的情况是

None
确实在定义时被求值(它的求值结果为
None
啊!),但是有条件地将
[]
分配给
L
的代码每次都会被编译并运行(条件通过)。


1
投票

默认参数仅计算一次。在

fun1
中,您有不断添加的相同列表。在
fun2
中,您将新的
[]
分配给参数,然后附加到它。与任何赋值一样,其范围将仅限于它发生的块。

© www.soinside.com 2019 - 2024. All rights reserved.