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()
foo.list.append(10)
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.
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!
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 http://effbot.org/zone/default-values.htm 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.