In Python, you can assign a default value to an optional varible like so:
def myFunction(x, y = 0):
print x + y
myFunction
can be called with either one or two arguments. If only one argument is supplied, y
will have a value of 0.
This is all perfectly straightforward and works just a you would expect, no matter what you put in the body of the function.
Suppose, however, that instead of integers, we want to do something with lists:
def listFunction(x, y = []):
y.append(x)
print y
The difference here is that lists are mutable. So if we call this function with two arguments, the list we pass as y
will be changed:
>> a = [1, 2, 3]
>> listFunction(4, a)
[1, 2, 3, 4]
>> a
[1, 2, 3, 4]
And that's fine. If we write a function like this, it's because we want to change a mutable variable. The problem arises with the default value. Because the default variable is only evaluated once, when the function is defined, it will also be changed by the code:
>> listFunction(1)
[1]
>> listFunction(1)
[1, 1]
>> listFunction(2)
[1, 1, 2]
And this is probably behaviour that we don't want. Now the default value of the variable depends on how many times the function has been called (and with which other variables). Unlike the case where we called the function with two variables, we also can't discard the modified list after using it: it will always hang around, and be accessed whenever that function is called again.
Obviously, you shouldn't modify a mutable default value like this. But a better practice is to not use mutable values as default values in the first place, so that the default value will stay the same, no matter what crazy thing you might do in the body of the function.