when is the function definition stage?
Look at "Function definitions" in the Python reference:
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 that 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, e.g.:
def whats_on_the_telly(penguin=None):
if penguin is None:
penguin = []
penguin.append("property of the zoo")
return penguin
The parameters are evaluated when the function definition is executed. If this is in a module, it happens when the module is imported. If it's in a class, it's when the class definition runs. If it's in a function, it happens when the function executes. Remember that a Python module is evaluated from top to bottom, and doesn't automatically have an explicit "main function" like some languages.
For example, if you put the function definition inside a function, you get a new copy of the function each time:
>>> def make_function():
... def f(value=[]):
... value.append('hello')
... return value
... return f
...
>>> f1 = make_function()
>>> f2 = make_function()
>>> f1()
['hello']
>>> f1()
['hello', 'hello']
>>> f2()
['hello']
The function definition creates a new function
object, assigns it various properties including the code, formal parameters, and default values, and stores it in a name in the scope. Typically this only happens once for any given function, but there are cases where a function's definition can be executed again.
My original thinking was that the name a_list gets discarded right after the function runs so whatever []
mutated to will be garbage collected.
Inside the body of the function, the name a_list
is available to the code. So the name, and the value it is pointing to, must both still be available. It is stored in the func_defaults
attribute of the function.
But then again, I'm wondering how I still get the same default value instead of a new [].
Because the []
is evaluated only when the function is defined, not when it is called, and the name a_list
points to the same object even across repeated calls. Again, if you want the alternative behavior, use something immutable like None
and check for it.