默认参数可变性和最小惊讶原则
Python 社区长期以来一直在努力解决“最小惊讶”原则,该原则旨在直观且符合预期的设计功能。然而,默认参数的可变性令人费解地偏离了这一原则。
考虑以下函数:
def foo(a=[]): a.append(5) return a
Python 新手可能会预期在不带参数的情况下调用此函数将始终生成一个列表只有一个元素:[5]。然而,实际行为要奇怪得多:
>>> foo() [5] >>> foo() [5, 5] >>> foo() [5, 5, 5] >>> foo() [5, 5, 5, 5]
这种行为引起了一些人的批评,他们认为这是一个“戏剧性的设计缺陷”。然而,它背后有一个逻辑解释。
Python 中的函数是一流的对象,这意味着它们可以像任何其他类型一样被操作并分配给变量。当执行 def 语句时,会创建一个函数对象。该对象不仅包含函数的代码,还包含其默认参数,这些参数存储为属性。
默认情况下,默认参数在函数定义时而不是在函数调用时计算。这意味着默认参数的状态可以在程序执行过程中发生变化,从而导致 foo 函数中观察到的行为。
此设计决策源于保持一致性的需要。如果在函数调用时计算默认参数,则 def 行将成为混合语句,其中部分绑定将在定义和调用时发生。这种方法会带来额外的复杂性和潜在的混乱。
正如 effbot 所指出的,这种行为并非没有实际应用。例如,考虑以下代码:
def a(): print("a executed") return [] def b(x=a()): x.append(5) print(x) a executed >>> b() [5] >>> b() [5, 5]
这里,x 的默认值在函数定义时计算,确保 a() 只被调用一次,无论 b() 被调用了多少次
总之,Python 中默认参数的可变性是一种有意的设计选择,它优先考虑一致性并符合一流函数的原则。虽然它最初看起来可能违反直觉,但它在函数实现方面提供了更好的控制和灵活性。
以上是为什么 Python 的默认参数可变性似乎违反了最小惊讶原则?的详细内容。更多信息请关注PHP中文网其他相关文章!