“最不令人惊讶”和可变默认参数
Python 的可变默认参数行为长期以来一直让初学者和经验丰富的开发人员感到困惑。像 foo(a=[]) 这样的函数会意外地在多次调用中累积值,这让许多人质疑其基本原理。
要理解这种看似有缺陷的设计的根源,我们必须深入研究 Python 函数的本质作为一流的对象。当定义一个函数时,它本质上是作为一个对象本身被评估的。这意味着默认参数(例如我们示例中的 a=[])成为函数对象的属性。
因此,当调用函数时,计算的不是默认参数值,而是计算的值指向在函数定义时创建的列表对象的属性。因此,对函数内列表所做的任何修改都会影响共享引用,从而解释了 a 的累积行为。
这种方法符合 Python 的“最少惊讶”哲学,该哲学优先考虑一致性和遵守对象 -导向原则。正如类中的实例变量可以随着时间的推移而改变一样,函数对象中的“成员数据”也可以。
这种行为也有一个实际目的:它允许函数具有在调用期间持续存在的状态。考虑以下示例:
def a(): print("a executed") return [] def b(x=a()): x.append(5) print(x) a executed >>> b() [5] >>> b() [5, 5]
这里,a() 返回的值由所有对 b() 的调用共享,允许在多次迭代中修改和保留列表。在函数执行时绑定默认参数将在每次调用 b() 时有效地创建一个新列表,从而使这种行为变得不可能。
总之,虽然 Python 的可变默认参数行为一开始看起来可能违反直觉,但它源于该语言一流的函数性质,符合面向对象编程和一致性的原则。
以上是为什么 Python 的可变默认参数行为会导致意外累积?的详细内容。更多信息请关注PHP中文网其他相关文章!