0

Could someone please explain to me why the following code treats the class variables n and lines differently, and how to get lines to behave the same way as n? Thanks in advance!

class A():
    n = 0
    lines = []

    @classmethod
    def Add(cls, line):
        cls.n += 1
        cls.lines.append(line)

class B(A):
    pass

class C(A):
    pass

B.Add('hello')
C.Add('world')

print(B.lines, B.n)
print(C.lines, C.n)

Output is:

['hello', 'world'] 1

['hello', 'world'] 1

i.e. The variable n is separate for the child classes whereas lines is not. Running on Python 3.7.4 for Windows 10.

Edit: I'd like to keep the implementation of lines inside the parent class if I can. I know I could re-declare lines in the child classes to get the behavior I want.

iain
  • 21
  • 3
  • Because lists are mutable and integers aren't. Appending is categorically different, `cls.lines = cls.lines + [line]` is the equivalent. See e.g. https://stackoverflow.com/q/1680528/3001761. – jonrsharpe May 19 '20 at 12:43
  • 2
    Inheritance treats both the same. *You* treat them differently by replacing the ``int`` but modifying the ``list``. – MisterMiyagi May 19 '20 at 12:45
  • The underlying mechanism is the same as with instances of the class vs. the class itself (as in the link): the *assignment to* `cls.n` creates separate versions in classes `B` and `C`, but the *modification of* `cls.lines` doesn't, because the list object is already there. – Karl Knechtel May 19 '20 at 12:50
  • " but the modification of cls.lines doesn't, because the list object is already there" - This is the subtlety I was missing and ```cls.lines = cls.lines + [line]``` worked as intended. Thanks. – iain May 19 '20 at 12:53

0 Answers0