我刚刚开始学习python,只是被默认的参数概念所震撼。
在python doc中提到,当遇到def
语句时,函数的默认参数值只计算一次。这使得不可变和可变默认函数参数的值之间存在很大差异。
>>> def func(a,L=[]):
L.append(a)
return L
>>> print(func(1))
[1]
>>> print(func(2))
[1, 2]
这里可变函数参数L保留最后一个赋值(因为默认值不是在函数调用期间计算的,就像在C中一样)
是默认参数的生命周期python中的值是程序的生命周期(就像C中的静态变量一样)?
修改:
>>> Lt = ['a','b']
>>> print(func(3,Lt))
['a', 'b', 3]
>>> print(func(4))
[1, 2, 4]
在函数调用func(3,Lt)
期间保留默认值L
,Lt
不会覆盖它。
那么默认参数有两个内存吗?一个用于实际默认值(带有程序范围)和其他用于传递对象的时间(带有函数调用范围)?
答案 0 :(得分:10)
由于参数是函数对象的属性,因此它通常与函数具有相同的生命周期。通常,函数从加载模块的那一刻起一直存在,直到解释器退出。
但是,Python函数是第一类对象,您可以尽早删除所有对函数的引用(动态)。然后垃圾回收器可以获得该函数,然后是默认参数:
>>> def foo(bar, spam=[]):
... spam.append(bar)
... print(spam)
...
>>> foo
<function foo at 0x1088b9d70>
>>> foo('Monty')
['Monty']
>>> foo('Python')
['Monty', 'Python']
>>> foo.func_defaults
(['Monty', 'Python'],)
>>> del foo
>>> foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined
请注意,您可以直接访问可写的func_defaults
属性(python 3中的__defaults__
),这样您就可以通过重新分配该属性来清除默认值。
答案 1 :(得分:3)
它至少与函数对象具有相同的生命周期(没有时髦的东西)。因此,如果加载的模块由所有其他模块卸载,并且没有其他引用,则功能对象及其成员可能会被销毁。
因为Python是垃圾收集的,所以在任何实际意义上你都不需要担心这个问题。如果对象逃脱,并且程序的某些其他部分有引用,它将会挂起。
如果你的观点是你想要依赖悬挂的物体并且不被重置,那么是的,你可以这样做,除非你有一些时髦的卸载模块,或者你有一些代码分配到变量上存储默认值的函数对象。