2

I am learning OOP in python, and I am surprised to find in another post that a parent class can access a class variable defined in child, like the example below. I can understand that child can access a class variable defined in parent bc of inheritance (or is it not inheritance but something else?). What makes this possible and does it imply a pool of class variables that a subclass can adds to (and its superclasses can access) when it inherits from a superclass?

class Parent(object):
    def __init__(self):
        for attr in self.ATTRS: // accessing class variable defined in child?
            setattr(self, attr, 0)

class Child(Parent):
    #class variable
    ATTRS = ['attr1', 'attr2', 'attr3']

    def __init__(self):
        super(Child, self).__init__()
6
  • 1
    You're accessing those variables using self. self is a direct instance of Child not Parent, hence it can access those stuff. That's how attribute lookup works. Commented Jul 30, 2015 at 20:48
  • is self in Parent class you are referring to? Commented Jul 30, 2015 at 20:50
  • 1
    @Pippi self is the same instance in both places - it is an instance (an object produced from a class) of whatever class you used to instantiate it (Child in this case). From the point of Child, it's an instance of itself. From the point of Parent, it's an instance of one of its subclasses. Commented Jul 30, 2015 at 20:53
  • 1
    @Pippi think of it this way: self always means "an instance of myself or my super- or subclasses" - so yes, methods on the parent class do have access to instance members (attributes or methods) of its subclasses. I recommend Raymond Hettinger's talk Python's Class Development Toolkit on this topic. Commented Jul 30, 2015 at 21:24
  • 1
    (He addresses this specific case at 34m38s) Commented Jul 30, 2015 at 21:31

2 Answers 2

4

The example is a bit twisted. The definition of the parent class is not complete, it references non-existing class variables, which only becomes apparent when instantiating the class or sub-classing it.

If you subclass as follows:

class Child2(Parent):
    def __init__(self):
        super(Child2, self).__init__()

Then instantiating the child class won't work:

Traceback (most recent call last):
  File "./cl.py", line 25, in <module>
    y=Child2()
  File "./cl.py", line 20, in __init__
    super(Child2, self).__init__()
   File "./cl.py", line 6, in __init__
    for attr in self.ATTRS:
AttributeError: 'Child2' object has no attribute 'ATTRS'

You would have to fix your parent as follows to make it work:

class Parent(object):
    ATTRS = None
    def __init__(self):
        if self.ATTRS:
            for attr in self.ATTRS:
                setattr(self, attr, 0)

The reason it works in your original example is that Python is an interpreted language, so the code is only evaluated at run-time.

Sign up to request clarification or add additional context in comments.

Comments

2

The parent is not accessing class variables because the self in __init__(self) is an instance of Child.

1 Comment

is self in Parent class you are referring to?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.