Accidental Static Class Variables

Problem

Using default argument parameters on the __init__ method on your class will create shared class variables instead of instance variables as you might expect! It is best demonstrated through some code snippets below:

Expected

When we use primitives that are “pass by value” as default parameters

class Foo:
    def __init__(self, bar = 3):
        self.bar = bar

f1 = Foo()
print(f1.bar) # 3
f2 = Foo(4)
print(f2.bar) # 4
print(f1.bar) # 3

Unexpected

When we use structures that are “passed by reference” as default parameters

class Foo:
    def __init__(self, bar_list = []):
        self.bar_list = bar_list

f1 = Foo([2, 2] )
print(f1.bar_list) # [2, 2]
f1.bar.append(4)
print(f1.bar) # [2, 2, 4]
f2 = Foo()
print(f2.bar) # [2, 2, 4] <- Wait what? Should this not be []

Conclusion

So it turns that putting mutable default parameters in the class constructor is not a good idea

Why

The reason behind this is the Python interpreter reads through your class definition only once.
Which means that the SAME mutable default parameter will be used by reference every time you instantiate a new instance of your class.