这是另一个默认参数问题。关键是当你写
def foo(value=VALUE):
函数内部的代码被编译并制成函数对象。是在这个时候——不是在通话时间!-- 存储默认参数。所以当你定义的时候已经B
太晚了:默认值foo
已经设置好了,改变VALUE
不会有任何效果。
如果这看起来很奇怪,那么假设foo
是一个全局函数:
default = 3
def foo(x=default): pass
foo
然后任何其他代码,任何地方,都可能搞砸
global default
default = 4
这可以说同样令人困惑。
要强制在运行时而不是编译时进行查找,您需要将它们放在函数中:
def foo(value=None):
self.value = self.VALUE if value is None else value
或(不完全相同但更漂亮)
self.value = value or self.VALUE
(这是不同的,因为它将任何'falsy' 值视为哨兵——也就是说,0
,[]
等都{}
将被 覆盖VALUE
。)
编辑:@mgilson 指出了另一种方法:
def foo(**kwargs):
self.value = kwargs.get("value", self.VALUE)
这更简洁,因为它不需要您创建标记值(例如None
or object()
,但它确实从根本上改变了参数规范,foo
因为现在它将接受任意关键字参数。您的电话。