Careful when using mutable types as default arguments in Python

As an intermezzo in the blog posts regarding my thesis, I’d like to point out an unexpected (or at least, unexpected for me) behaviour in Python’s way of constructing default arguments.

Suppose we have the following python class MyClass, with an initializer with a default list parameter:

class MyClass:
def __init__(self, list=[]):
self.list = list

What happens if we initialize two different instances of this class, and modify one of them by adding an item to its underlying list?

foo = MyClass()
bar = MyClass()


print 'foo.list: ', foo.list
print 'bar.list: ', bar.list

Well, the output is the following:

foo.list: [10]
bar.list: [10]

What happened here? The default value for the list parameter in the class initializer is evaluated only once, when the class is loaded, and therefore only one instance of list is created. In other words, all instances of MyClass using the default value for list will share the same list instance, so when one of them is modified, all of them are.

2 Responses to Careful when using mutable types as default arguments in Python

  1. Martin Verzilli mverzilli says:

    Hey, that’s weird! Are you sure there’s not a modifier or something on the sort to change that behavior? If there isn’t, I’ll have to believe that van Rossum wants us to use default arguments just with immutable types!

    • Santiago Palladino spalladino says:

      Yep, it is weird. I made a quick google search and it seems that I’m not the only one surprised with this behaviour. Check for a good explanation on this design decision.

      If you take into account that the “def” keyword in python is executed when encountered, and its executions defines a new function and requires all of its arguments to be evaluated, this behaviour actually makes sense.

Leave a Reply

Your email address will not be published. Required fields are marked *

six − 1 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>