Python 对函数默认参数的处理
一个以可变对象为默认参数的函数:
1 | class A: |
从结果可以看出,Python 在解析时便已经创建好了默认参数 a 的值。函数 f 在调用时采用了同一个对象,而不是每次调用时重新创建新的对象。这一点与 C++
的处理方式不同。
f.__defaults__
在 Python 中,函数属于一等公民(first-class)。函数可当作一个对象,拥有自己的属性与方法。而默认参数则存在与函数的一个属性中。
1 | In [28]: def f(a, b=1): |
Python 在解析代码时,便会将默认参数存于 f.__defaults__
中。
在 CPython 的 (funcobject.h)[https://github.com/python/cpython/blob/master/Include/funcobject.h] 中也可以看到,PyFunctionObject
的一个属性便是 func_defaults
, 对应 Python 中每个函数中的 __defaults__
属性
默认参数 与 闭包
以下是一个经常被提起的关于理解闭包的一段代码
1 | def test(): |
在这里中,匿名函数中的变量 i
并没有在声明时便被求值,而是在匿名函数被调用时才被求值。因为 i
来自于 test
函数,且在匿名函数被调用时,循环已经结束,所以 i
的值已经变成 4。
但如果想让 i
在匿名函数声明时便被求值该如何做呢?
以下代码便借助默认参数解决问题:
1 | def test(): |
与第一段代码相比,第二段代码中的 i
在匿名函数声明时就被求值,而且因此,每个匿名函数拥有的默认参数 i
的值都不相同。这样解决了问题。