回答

收藏

“Least Astonishment”和可变默认参数

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

任何修补 Python 时间足够长的人会被以下问题咬伤(或撕成碎片):+ N) i6 q+ `7 u1 s
    def foo(a=     a.append(5)    return a9 R( u3 X! |3 @7 V8 R
Python 新手会期望这个函数总是回到只有一个元素的列表:[5]. 结果却大不相同,而且非常惊人(对于新手来说):
+ M" N1 P) H# G/ a+ x
    >>> foo()[5]>>> foo()[5,5]>>> foo()[5,5,5]>>> foo(5,5,5,5>>> foo()4 P, g- D) ~& ]4 v
我的一位经理第一次遇到了这个功能,并称之为语言的戏剧性设计缺陷。我回答说,这种行为有一个潜在的解释。如果你不了解内部情况,那真是令人费解和惊讶。然而,我不能(对自己)回答以下问题:在函数定义而不是函数执行时绑定默认参数的原因是什么?我怀疑经验丰富的行为是否有实际用途(谁真的在 C 使用静态变量没有滋生错误?* C) X9 h2 @- s
编辑. H. Q3 R: `% @+ W+ J
我进一步阐述:  U/ F9 p  \3 t( W* M
    >>> def a():...     print("a executed")...     return []... >>>            >>> def b(x=a()):...     x.append(5)...     print(x)... a executed>>> b()[5]>>> b()[5,5]
    $ U1 _5 f- r5 q$ r0 L8 K5 a9 Y
对我来说,设计决策似乎与把参数放在哪里有关:在函数内部,还是与之在一起?
2 G& J) i* x1 V, b1 r" m+ d( p) B绑定函数内部意味着x当函数被调用而不是定义时,它有效地绑定到指定的默认值,这将带来严重的缺陷:def定义时会发生绑定部分(函数对象),调用函数时会发生部分(默认参数分配)。4 v7 H5 O- O) b/ k+ E3 k
实际行为更加一致:银行的所有内容都在执行银行时进行评估,这意味着在函数定义中。# c9 a5 x% V& M4 f5 \6 i1 F
                                                                1 Z1 y7 k7 J( ?& w
    解决方案:                                                                5 T/ V! Q0 l% b7 l/ k
                                                                任何修补 Python 时间足够长的人会被以下问题咬伤(或撕成碎片):
* w4 |& ^8 \' O) O
    def foo(a=     a.append(5)    return a
    / W# c" a+ N8 _8 b
Python 新手会期望这个函数总是回到只有一个元素的列表:[5]. 结果大不相同,非常惊人(对于新手来说):
6 `) h; G  T3 e2 z6 U0 K1 ?! {+ s
    >>> foo()[5]>>> foo()[5,5]>>> foo()[5,5,5]>>> foo(5,5,5,5>>> foo()0 {' x' I0 S4 A; k# |6 y7 y
我的一位经理第一次遇到了这个功能,并称之为语言的戏剧性设计缺陷。我回答说,这种行为有一个潜在的解释。如果你不了解内部情况,那真是令人费解和惊讶。然而,我不能(对自己)回答以下问题:在函数定义而不是函数执行时绑定默认参数的原因是什么?我怀疑经验丰富的行为是否有实际用途(谁真的在 C 使用静态变量没有滋生错误?
/ G' D' m; L0 @$ R2 y; \* |编辑
: M+ x9 \2 p1 @) Z/ \我进一步阐述:
+ A& {6 ^  c1 p$ U% J* M. r3 P  F& m
    >>> def a():...     print("a executed")...     return []... >>>            >>> def b(x=a()):...     x.append(5)...     print(x)... a executed>>> b()[5]>>> b()[5,5]
    3 A! @: i! ]2 g3 i" [7 f* N
对我来说,设计决策似乎与把参数放在哪里有关:在函数内部,还是与之在一起?
; u6 H/ m. q5 j9 i3 z4 f绑定函数内部意味着x当函数被调用而不是定义时,它有效地绑定到指定的默认值,这会带来一个严重的缺陷:def定义时会发生绑定部分(函数对象),调用函数时会发生部分(默认参数分配)。/ h: x5 |8 g4 [* i6 _8 y: U9 W% d
实际行为更加一致:银行的所有内容都在执行银行时进行评估,这意味着在函数定义中。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则