2

Suppose I have the following code:

class ParentClass():
    myList = []

    def __init__(self):
        print("Parent class constructor")

class ChildA(ParentClass):
    def __init__(self):
        print("Child A constructor")

    def add_elem(self, item):
        self.myList.append(item)
        print(f"Added item by Child A, current length: {len(self.myList)}")

class ChildB(ParentClass):
    def __init__(self):
        print("Child B constructor")

    def add_elem(self, item):
        self.myList.append(item)
        print(f"Added item by Child B, current length: {len(self.myList)}")

a = ChildA()
a.add_elem(1)
a.add_elem(1)

b = ChildB()
b.add_elem(1)

When I run it (Python 3.9.3), I get this output:

Child A constructor
Added item by Child A, current length: 1
Added item by Child A, current length: 2
Child B constructor
Added item by Child B, current length: 3

This suggests that the parent class that the children classes inherit from has one backing instance, and because I didn't explicitly set myList to [] in the constructor, it uses the same backing memory, even for two different children classes.

  1. Is this assumption correct?
  2. What are valid uses for this design? When I first discovered this behavior I thought it might be a language bug, but I feel like that's quite unlikely.

I worked around this by just explicitly setting myList to [] in the parent constructor, but I am bewildered by this behavior, as it was not the behavior I was expecting (I would expect the length of myList after the first call to ChildB to be 1).

captainGeech
  • 302
  • 1
  • 5
  • 17

1 Answers1

1

I worked around this by just explicitly setting myList to [] in the parent constructor, but I am bewildered by this behavior, as it was not the behavior I was expecting.

That's correct. What you've done is define a variable on the class itself, not on instances of the class. The correct way to define instance variables is in the constructor.

class ParentClass():

    def __init__(self):
        print("Parent class constructor")
        self.myList = []
Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116