標籤:
add by zhj: 在Python文檔中清楚的說明了預設參數是怎麼工作的,如下
"Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that the same “pre-computed” value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function
def whats_on_the_telly(penguin=None): if penguin is None: penguin = [] penguin.append("property of the zoo") return penguin
"
參見https://docs.python.org/2/reference/compound_stmts.html#function-definitions
原文:Python函數參數預設值的陷阱和原理深究
這個問題的答案在 StackOverflow 上可以找到答案。這裡將得票數最多的答案最重要的部分摘錄如下:
Actually, this is not a design flaw, and it is not because of internals, or performance.
It comes simply from the fact that functions in Python are first-class objects, and not only a piece of code.
As soon as you get to think into this way, then it completely makes sense: a function is an object being evaluated on its definition; default parameters are kind of “member data” and therefore their state may change from one call to the other - exactly as in any other object.
In any case, Effbot has a very nice explanation of the reasons for this behavior in Default Parameter Values in Python.
I found it very clear, and I really suggest reading it for a better knowledge of how function objects work.
在這個回答中,答題者認為出於Python編譯器的實現方式考慮,函數是一個內部一級對象。而參數預設值是這個對象的屬性。在其他任何語言中,對象屬性都是在對象建立時做綁定的。因此,函數參數預設值在編譯時間綁定也就不足為奇了。
然而,也有其他很多一些回答者不買賬,認為即使是first-class object
也可以使用closure
的方式在執行時綁定。
This is not a design flaw. It is a design decision; perhaps a bad one, but not an accident. The state thing is just like any other closure: a closure is not a function, and a function with mutable default argument is not a function.
甚至還有反駁者拋開實現邏輯,單純從設計角度認為:只要是違背程式猿基本思考邏輯的行為,都是設計缺陷!下面是他們的一些論調:
> Sorry, but anything considered “The biggest WTF in Python” is most definitely a design flaw. This is a source of bugs for everyone at some point, because no one expects that behavior at first - which means it should not have been designed that way to begin with.
The phrases “this is not generally what was intended” and “a way around this is” smell like they’re documenting a design flaw.
好吧,這麼看來,如果沒有來自於Python作者的親自澄清,這個問題的答案就一直會是一個謎了。
Python函數參數預設值的陷阱和原理深究(轉)