Anyone who has used Python for a long time will be troubled (or torn to pieces) by the following problems:
def foo(a=[]): a.append(5) return a
Newbies to python will expect that this function, called without arguments, will always return a list with only one element: [5]
. The results are very different and quite surprising (for newbies):
>>> foo() [5] >>> foo() [5, 5] >>> foo() [5, 5, 5] >>> foo() [5, 5, 5, 5] >>> foo()
One of my managers once encountered this feature for the first time and called it "a dramatic design flaw" in the language. I replied that there was an underlying explanation for this behavior, and that it would indeed be very puzzling and unexpected if one didn't understand its internals. However, I can't answer (to myself) the following question: What is the reason for binding default parameters at function definition time instead of at function execution time? I doubt the experienced behavior has any practical use (who actually uses static variables in c without breeding bugs?)
edit:
baczek gave an interesting example. In conjunction with most of your comments, especially utaal's, I elaborate further:
def a(): print("a executed") return [] def b(x=a()): x.append(5) print(x) a executed >>> b() [5] >>> b() [5, 5]
To me, the design decision seems to be related to where to place the parameter scope: inside the function, or "with" the function?
Binding inside a function means that x
effectively binds to the specified default value when the function is called, rather than to the definition, which brings serious drawbacks: def
The line will be "mixed" in that part of the binding (of the function object) will happen at definition time and part (assignment of the default parameters) will happen at function call time.
The actual behavior is more consistent: when the line is executed, i.e. at function definition time, all contents of the line are evaluated.
Actually, this is not a design flaw, nor is it for internal or performance reasons. It stems from the fact that functions in Python are first-class objects, not just pieces of code.
It makes perfect sense once you think about it this way: a function is an object that evaluates according to its definition; default parameters are a kind of "member data", so their state may change from one call to another - Exactly like any other object.
Anyway, effbot (Fredrik Lundh) has a good explanation of the reason for this behavior in Default Parameter Values in Python. I found it very clear and I really recommend reading it to better understand how function objects work.
The above is the detailed content of 'Least Surprise' and Variable Default Arguments. For more information, please follow other related articles on the PHP Chinese website!