Accidental Static Class Variables


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:


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

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

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


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]
print( # [2, 2, 4]
f2 = Foo()
print( # [2, 2, 4] <- Wait what? Should this not be []


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


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.