python function default parameter is evaluated only once? [duplicate]
I am a python beginner, reading 'python tutorial', it says if we have a function:
def f(a, L=[]):
L.append(a)
return L
print f(1)
print f(2)
print f(3)
This will print
[1]
[1, 2]
[1, 2, 3]
Because the default value is evaluated only once and list is a mutable object. I can understand it.
And it says continue, if we don't want the default to be shared between subsquent calls, we can:
def f(a, L=None):
if L is None: #line 2
L = []
L.append(a)
return L
print f(1)
print f(2)
print f(3)
and this will output:
[1]
[2]
[3]
But why? How to explain this. We know default value is evaluated only once
, and when we call f(2), L is not None and that if
(in line 2) can not be true, so L.append(a) == [1, 2]. Could I guess the default value is evaluated again for some reason , but what is 'some reason', just because the python interpreter see if L is None: L = []
Python passes parameters to functions by value; So for objects, the value passed is a reference to the object, not a new copy of the object.
That, along with the following part of the official docs is what helped me understand it better (emphasis mine):
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. [...] A way around this is to use None as the default, and explicitly test for it in the body of the function [...]
Putting it all together:
If you define the default for a parameter to be a mutable object (such as []
) then the "pre-computed" value is the reference to that object, so each call to the function will always reference the same object, which can then be mutated across multiple invocations of the function.
However, since None
is an immutable built-in type, the "pre-computed" value for a default of None
is simply that. So the parameter will be None
each time you call the function.
Hopefully that helps! I do think that the tutorial could have had better wording, because I was also confused by that at first.
"The default value is only evaluated once" does not mean that a parameter with a default retains its value between invocations of the function. It means that the expression which you specify (the None
part of def f(a, L=None)
) is evaluated once, and the object it results in is stored in a hidden location and re-used if no value for that parameter is given at call. Parameters are still reset to the value (default or not) at every invocation.
In your second example you have a variable L
. At first L
refers to None
. You repoint it to a new empty list on each invocation, then mutate that new list. Remember L = []
is the same as L = list()
In your first example, however, L is set to the new list once at function declaration. L isn't reset to []
on each invocation of the function. So you are always mutating the same list.