Python默认参数求值
我正在阅读python文档2.7.10版中的python教程,遇到了类似的内容 代码Python默认参数求值,python,python-2.7,arguments,default-arguments,Python,Python 2.7,Arguments,Default Arguments,我正在阅读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
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()
的输出正常。但是为什么每次在fun2()
中调用L=None
,默认参数只计算一次。在fun1
中,您的列表与您一直添加到的列表相同。在fun2
中,为参数指定一个新的[]
,然后将其追加。与任何赋值一样,它的范围将限于它发生在的块。定义函数时,默认参数的值将被计算,但函数体只会被编译。您可以通过属性检查函数定义的结果。有一个\uuuuu defaults\uuuuuu
属性包含默认值,还有一个\uuuuuuu code\uuuuu
属性包含主体(因此这些属性是在定义函数时创建的)
在第二个示例中发生的情况是,
None
确实在定义中得到计算(它的计算结果为None
duh!),但是有条件地将[]
赋值给L
的代码只会被编译,并且每次都会运行(条件通过)。L=[]
在函数声明中,Python基本上是这样做的:
- 此函数有一个名为
L
- 它的默认参数是
,让我们把这个特殊的[]
放在一边,在没有为[]
传递参数时使用它L
- 每次调用函数时,创建一个变量
,并为其分配传递的参数或我们先前设置的值L
因此,
[]
部分将执行一次,这将创建一个列表对象,该对象被放在一边并保留在周围,这就是为什么如果您修改它,它会累积更改。同样的事情也发生在None
上,但是None
并没有被修改,也不能改变,所以你没有看到任何奇怪的副作用None
仍然只被“执行”一次,而特定的None
值也像列表一样被放在一边,只是你没有对None
值本身做任何事情。“为什么L=None
不会每次都被调用”–我不知道你想说什么。我假设L=None
每次都会被调用/执行。这就是为什么在第二个函数fun2()
中,如果L为None,则条件每次都为true。默认参数在函数声明中求值。空列表是可变的,所以在每个函数调用中都编辑相同的列表。附加到它不会创建新对象。如果没有,则在函数体中创建列表。每次从函数返回新列表时。但我正在将fun2()中的if
条件中的L=None
更改为L=[]
。为什么此赋值/更改不是永久性的或对其他后续函数调用不可见。再次说明:每次调用函数时,都会创建变量L
,并为其赋值。值[]
是永久的,而不是与L
的关联。值[]
存储您的内容。将附加到它,而不是L
。内存中的永久对象[]
与指向它的变量L
不同。