A reminder about python argument defaults
There’s an issue I’ve seen plenty of times before, but caught me off guard again today. Hence I figured I’d write about it as a reminder to myself. The morale of the story is that you should not pass non-static defaults into arguments in a method’s definition in python.
def __init__(self, some_arg=[]): self.some_arg = some_arg
This will cause issues if you create more than one instance of the class with no value passed in for some_arg. It will end up re-using the same list, and different instances of the objects will share the same self.arg.
For example if I were to do:
first_object = SomeClass() first_object.some_arg.append(1) print first_object.some_arg # prints out [1] second_object = SomeClass() second_object.some_arg.append(2) print second_object.some_arg # will print out [1,2] even though we never appended 1 to the second object
What’s happening is that both first_object and second_object are referencing the same list, which was instantiated at the definition of the class. A somewhat non-intuitive pitfall, but makes sense if you think about it. This is also true for other mutable objects, so be careful what you set the default to.
A way around this, is to set the default to None and create a new list in such a case within the execution of __init__.
def __init__(self, some_arg=None): self.some_arg = some_arg or []
Anyways, just a friendly reminder to be careful about argument defaults!
Also an excerpt about it from Effective Python: