回答

收藏

“Least Astonishment”和可变默认参数

技术问答 技术问答 212 人阅读 | 0 人回复 | 2023-09-12

任何修补 Python 时间足够长的人会被以下问题咬伤(或撕成碎片):6 Q: L# p+ H& a% p) l, W
    def foo(a=     a.append(5)    return a8 Q1 H) g2 z* V
Python 新手会期望这个函数总是回到只有一个元素的列表:[5]. 结果却大不相同,而且非常惊人(对于新手来说):/ f0 y& c& o2 W6 p
    >>> foo()[5]>>> foo()[5,5]>>> foo()[5,5,5]>>> foo(5,5,5,5>>> foo()/ ]8 o" S9 \" U3 X, v
我的一位经理第一次遇到了这个功能,并称之为语言的戏剧性设计缺陷。我回答说,这种行为有一个潜在的解释。如果你不了解内部情况,那真是令人费解和惊讶。然而,我不能(对自己)回答以下问题:在函数定义而不是函数执行时绑定默认参数的原因是什么?我怀疑经验丰富的行为是否有实际用途(谁真的在 C 使用静态变量没有滋生错误?- l; R  c' h; ^6 h+ c
编辑$ ?0 }- F& q! _* d( |% F
我进一步阐述:1 m4 }- |: u. g: s8 J
    >>> def a():...     print("a executed")...     return []... >>>            >>> def b(x=a()):...     x.append(5)...     print(x)... a executed>>> b()[5]>>> b()[5,5]4 x, x; {0 ^: o  A# e; y& T
对我来说,设计决策似乎与把参数放在哪里有关:在函数内部,还是与之在一起?
# E8 w: G3 {/ D2 {绑定函数内部意味着x当函数被调用而不是定义时,它有效地绑定到指定的默认值,这将带来严重的缺陷:def定义时会发生绑定部分(函数对象),调用函数时会发生部分(默认参数分配)。9 [# H/ K+ v! G# c) D7 O% F9 ~, ]
实际行为更加一致:银行的所有内容都在执行银行时进行评估,这意味着在函数定义中。
' K7 E; ~% d2 ?+ D1 b& t                                                               
  j" R# o, w" ]! d* s" }/ Z$ x) ^    解决方案:                                                                1 W9 F4 Z) I  [# [9 b- D
                                                                任何修补 Python 时间足够长的人会被以下问题咬伤(或撕成碎片):
7 T! n+ x5 u1 W2 t* {
    def foo(a=     a.append(5)    return a: {% a$ Z' ~- P$ w$ s" s
Python 新手会期望这个函数总是回到只有一个元素的列表:[5]. 结果大不相同,非常惊人(对于新手来说):# F/ y1 F& Z& k
    >>> foo()[5]>>> foo()[5,5]>>> foo()[5,5,5]>>> foo(5,5,5,5>>> foo()
    " \7 R2 A, l2 M" G
我的一位经理第一次遇到了这个功能,并称之为语言的戏剧性设计缺陷。我回答说,这种行为有一个潜在的解释。如果你不了解内部情况,那真是令人费解和惊讶。然而,我不能(对自己)回答以下问题:在函数定义而不是函数执行时绑定默认参数的原因是什么?我怀疑经验丰富的行为是否有实际用途(谁真的在 C 使用静态变量没有滋生错误?
7 W$ @- M  D) v  `8 B2 C7 o编辑
% _/ V7 H$ f$ e我进一步阐述:
& F5 t3 A  T8 r8 s( O
    >>> def a():...     print("a executed")...     return []... >>>            >>> def b(x=a()):...     x.append(5)...     print(x)... a executed>>> b()[5]>>> b()[5,5]
    0 T# _6 F2 Q% ]) F0 i6 |1 W0 A/ _
对我来说,设计决策似乎与把参数放在哪里有关:在函数内部,还是与之在一起?
% F( e+ J$ {. [1 @; m绑定函数内部意味着x当函数被调用而不是定义时,它有效地绑定到指定的默认值,这会带来一个严重的缺陷:def定义时会发生绑定部分(函数对象),调用函数时会发生部分(默认参数分配)。2 ^! f# i0 u4 y; P/ F
实际行为更加一致:银行的所有内容都在执行银行时进行评估,这意味着在函数定义中。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则