Today I learned something interesting about the way Python functions behave with default parameter values: avoid using mutable objects such as lists as default values for function parameters.
What’s the problem?
Default parameter values are evaluated when function is evaluated. Which means default parameter values are only evaluated once. If you use a mutable value type as a default parameter value you will find the default parameter value will not reset each time you call the function. Take a look at the example below:
def favorite_toppings(name, toppings=[]): toppings.append("pepperoni") return print("{0}'s favorite toppings are {1}".format(name, ', '.join(toppings)))
If you call favorite_toppings
several times without passing in an argument for toppings
you get the following output:
>>> favorite_toppings("Ashley") Ashley's favorite toppings are pepperoni >>> favorite_toppings("Ashley") Ashley's favorite toppings are pepperoni, pepperoni >>> favorite_toppings("Ashley") Ashley's favorite toppings are pepperoni, pepperoni, pepperoni
A workaround
The state of toppings
does not reset to an empty list with each sequential call to favorite_toppings
. To avoid this problem refactor the method setting None
as the default type and check to see if an argument has been passed in. Take a look at the revised code below:
def favorite_toppings(name, toppings=None): if toppings is None: toppings = [] toppings.append("pepperoni") return print("{0}'s favorite toppings are {1}".format(name, ', '.join(toppings)))
If you call favorite_toppings
three more times with the revised method the output is:
>>> favorite_toppings("Ashley") Ashley's favorite toppings are pepperoni >>> favorite_toppings("Ashley") Ashley's favorite toppings are pepperoni >>> favorite_toppings("Ashley") Ashley's favorite toppings are pepperoni
So remember
Always use immutatable objects such as strings and integers for default parameter values. For more details on functions definitions in Python, read the docs here.
Fortunately, this is not a lesson I had to learn the hard way, but rather something I had either missed when I first learned how to program in Python or forgot it was something I should avoid in the years since learning Python. A quick language comparison: in C# you will get compile errors if you try to use an mutable value as a default parameter value.