“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实际行为更加一致:银行的所有内容都在执行银行时进行评估,这意味着在函数定义中。 |
|
|
|
|
|