"Least Astonishment" and the Mutable Default Argument
Python's surprising behavior with mutable default arguments has puzzled countless developers. Consider the following:
def foo(a=[]): a.append(5) return a
Intuitively, one might expect this function to always return a list containing only [5] when called without parameters. However, this assumption is shattered by the actual output:
>>> foo() [5] >>> foo() [5, 5] >>> foo() [5, 5, 5] >>> foo() [5, 5, 5, 5]
So, what's going on?
The key lies in Python's first-class function objects. When a function is defined, it's evaluated immediately, including the evaluation of default arguments. In the case of foo, the default value for a is evaluated to an empty list. However, this list is stored within the function object itself, making it mutable for subsequent calls.
Unlike in languages like C, function parameters in Python are not static variables that are evaluated at compile-time. Instead, they are bound to objects that may change over time. This concept of "member data" in function objects explains the astonishing behavior we observe with mutable default arguments.
As the effbot notes in Default Parameter Values in Python, this behavior is logical and consistent with the way other objects work:
"Any object can have its state changed from one call to another. Why should functions be different?"
Therefore, while this behavior may initially be surprising, it ultimately follows the principle of "least astonishment" by aligning with Python's object-oriented nature and the expectations of mutable object behavior.
The above is the detailed content of Why Does Python's Mutable Default Argument Behavior Seem So Surprising?. For more information, please follow other related articles on the PHP Chinese website!