一、函数的默认值参数在定义的时候就已经赋值了,而不是在调用的时候才赋值:
i = 1 def f(a=i): print(a) # 1 在创建这个函数的时候就已经给a赋值了,并不是在调用函数的时候才给a赋值。所以a是1 print(i) # 6 在调用函数的时候此时i的值是6 i = 6 f()
二、默认值参数如果是一个可变对象:list set dist 自定义对象等
同理 L=[] 是在定义的时候就赋值了,因为在调用的时候没有重先赋值,所以它就一直引用同一个对象
def f(a,L=[]): L.append(a) print(L) f(1) # [1] f(2) # [1, 2] f(3) # [1, 2, 3]
再如:有默认值参数 p 在定义的时候就赋值了,如果你不重先赋值,它就一直引用这个对象
所以,f(1) f(2)应该能够理解
f(3...)重先赋值,所以引用的是新的值
f(4)没有赋值,所有还是引用原来的值
class PP: def __init__(self,name,age): self.name = name self.age = age def f(a, p=PP(‘tangjun‘, 42)): p.age += a print(p.name, p.age) f(1) # tangjun 43 f(2) # tangjun 45 f(3, PP(‘xdong‘, 20)) # xdong 23 f(4) # tangjun 49
三,默认值参数如果是一个可变对象,怎么避免引用同一个对象:
把默认值设置成None,python并不会把None当成一个可变对象
def f(a,L=None): if L == None: L = [] L.append(a) print(L) f(1) # [1] f(2) # [2] f(3) # [3]
总结:
函数形参的值在定义函数时就被创建(注意,不是在调用函数时才被创建),且永不改变,除非调用函数时重先给它传递一个参数
参数a:引用了 i 的值:1,但是在调用函数 f() 的时候,虽然 i 的值已经改变,但是a的值不会改变,因为定义的时候就确定了(除非调用函数时给它传一个别的值。)
使用可变对象作为函数参数的默认值时,多次调用可能会导致意料之外的情况。如下
参数L :在定义函数的时候引用了一个[],然后每次调用函数都不重先赋值,所以 L 一直引用同一个对象,并且这个对象不停的被添加新的元素,
结论,函数的形参在定义函数时就被赋值了,而不是调用的时候才赋值,准确的说调用的时候是重先赋值(如果传递了实参的话)
思考,以前遇到过想编写一个功能独立的函数,函数在多次调用期间想共享一个变量(全局变量),又不想节外生枝在函数外创建这个全局变量,以破坏函数功能的相对独立性(函数依赖于函数体外的全局变量)。遇到这种情况可以把这个全局变量定义成有默认值的形参就形了。
原文:https://www.cnblogs.com/tangjun112/p/13956891.html