Don't use mutable default parameters in Python

When writing a Python function, you may need a list as default parameter. One may write a function like this:

def test(q=[]):
    q.append(1)
    return q

This function seems to be well written, whereas when calling it without a given parameter q, you may run into trouble.

>>> test()
[1]
>>> test()
[1, 1]
>>> test()
[1, 1, 1]
>>> test()
[1, 1, 1, 1]

This is weird at first, as required the function should return the list [1] after calling without a give parameter. However after carefully examining the code, we found that all of the returned list have the same ids.

>>> id(test())
4508921728
>>> id(test())
4508921728
>>> id(test())
4508921728

This means that all these function calls are using the same object(the default parameter q), for that reason they are always calling append method from the same list, and returns it.

Default Parameters in Python must be immutable

Everything is an object in Python, including functions. Default parameter in a function is like a member variable in an object, when the definition of the function is executed, the function object is initiated, and the default parameter values([]) are evaluated and the default parameters(q) is a reference to the parameter object.

>>> from datetime import datetime
>>> def test_time(q=datetime.now()):
...     return q
...
>>> test_time()
datetime.datetime(2014, 9, 8, 23, 58, 23, 700633)
>>> test_time()
datetime.datetime(2014, 9, 8, 23, 58, 23, 700633)
>>> test_time()
datetime.datetime(2014, 9, 8, 23, 58, 23, 700633)

In the above example, q is established along with the definition code of the function test_time being executed, you may notice that they are always returning the same time(time the definition code of the function test_time being executed at) instead of the current time. For that reason, mutable default parameters are not a good practice in Python.

About the author

Hey, I'm Peixuan, a software engineer. I write posts about things I learned.

dinever