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