回答

收藏

“Least Astonishment”和可变默认参数

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

任何修补 Python 时间足够长的人会被以下问题咬伤(或撕成碎片):( M% V  @1 D: C8 _
    def foo(a=     a.append(5)    return a
    9 U% V  f" B9 `! z& Z+ J0 ]; g# g
Python 新手会期望这个函数总是回到只有一个元素的列表:[5]. 结果却大不相同,而且非常惊人(对于新手来说):
' ?: O6 ?2 P/ j: A
    >>> foo()[5]>>> foo()[5,5]>>> foo()[5,5,5]>>> foo(5,5,5,5>>> foo()
      @1 n# Y" F% v1 M) z( D. t8 Y3 y
我的一位经理第一次遇到了这个功能,并称之为语言的戏剧性设计缺陷。我回答说,这种行为有一个潜在的解释。如果你不了解内部情况,那真是令人费解和惊讶。然而,我不能(对自己)回答以下问题:在函数定义而不是函数执行时绑定默认参数的原因是什么?我怀疑经验丰富的行为是否有实际用途(谁真的在 C 使用静态变量没有滋生错误?
' n+ m1 d% t. ~7 R编辑4 L0 _$ t" q& f/ h
我进一步阐述:
: p7 m4 r# @* I& c3 T, W0 F2 O( A
    >>> def a():...     print("a executed")...     return []... >>>            >>> def b(x=a()):...     x.append(5)...     print(x)... a executed>>> b()[5]>>> b()[5,5]# K! g; q& I. X
对我来说,设计决策似乎与把参数放在哪里有关:在函数内部,还是与之在一起?
; j2 P# P" e- z! p绑定函数内部意味着x当函数被调用而不是定义时,它有效地绑定到指定的默认值,这将带来严重的缺陷:def定义时会发生绑定部分(函数对象),调用函数时会发生部分(默认参数分配)。' l) s6 N, `, m
实际行为更加一致:银行的所有内容都在执行银行时进行评估,这意味着在函数定义中。
4 M5 C9 P9 Q0 C( _' f9 J                                                               
2 Q7 o+ s. h& I% d3 V1 _    解决方案:                                                                6 i$ y) f5 @& l
                                                                任何修补 Python 时间足够长的人会被以下问题咬伤(或撕成碎片):3 t' Q2 H" w, n
    def foo(a=     a.append(5)    return a
    # W" N" W0 D! E! q
Python 新手会期望这个函数总是回到只有一个元素的列表:[5]. 结果大不相同,非常惊人(对于新手来说):
4 P  @8 `+ |& q- }9 I
    >>> foo()[5]>>> foo()[5,5]>>> foo()[5,5,5]>>> foo(5,5,5,5>>> foo()
    4 t3 q2 P2 H) ]7 g9 l
我的一位经理第一次遇到了这个功能,并称之为语言的戏剧性设计缺陷。我回答说,这种行为有一个潜在的解释。如果你不了解内部情况,那真是令人费解和惊讶。然而,我不能(对自己)回答以下问题:在函数定义而不是函数执行时绑定默认参数的原因是什么?我怀疑经验丰富的行为是否有实际用途(谁真的在 C 使用静态变量没有滋生错误?
0 g/ L* P& u) O编辑
4 w& ~2 J1 H' e3 x. F. }" ~我进一步阐述:9 y! g; Q# |2 E; j2 r8 t4 S1 T0 z
    >>> def a():...     print("a executed")...     return []... >>>            >>> def b(x=a()):...     x.append(5)...     print(x)... a executed>>> b()[5]>>> b()[5,5]" h/ p  ^7 B$ M- w% g
对我来说,设计决策似乎与把参数放在哪里有关:在函数内部,还是与之在一起?: F- a% d# i* L% U9 |
绑定函数内部意味着x当函数被调用而不是定义时,它有效地绑定到指定的默认值,这会带来一个严重的缺陷:def定义时会发生绑定部分(函数对象),调用函数时会发生部分(默认参数分配)。
: n, _3 E& l. I实际行为更加一致:银行的所有内容都在执行银行时进行评估,这意味着在函数定义中。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则