Accessing attribute from parent class inside child class

During the class definition, none of the inherited attributes are available:

>>> class Super(object):
    class_attribute = None
    def instance_method(self):
        pass


>>> class Sub(Super):
    foo = class_attribute



Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    class Sub(Super):
  File "<pyshell#7>", line 2, in Sub
    foo = class_attribute
NameError: name 'class_attribute' is not defined
>>> class Sub(Super):
    foo = instance_method



Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    class Sub(Super):
  File "<pyshell#9>", line 2, in Sub
    foo = instance_method
NameError: name 'instance_method' is not defined

You can’t even access them using super, as the name of the subclass isn’t defined within the definition block*:

>>> class Sub(Super):
    foo = super(Sub).instance_method



Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    class Sub(Super):
  File "<pyshell#11>", line 2, in Sub
    foo = super(Sub).instance_method
NameError: name 'Sub' is not defined

The only way to access the inherited attributes at definition time is to do so explicitly, using the name of the superclass:

>>> class Sub(Super):
    foo = Super.class_attribute


>>> Sub.foo is Super.class_attribute
True

Alternatively you can access them within class or instance methods, but then you need to use the appropriate prefix of the class (conventionally cls) or instance (conventionally self) parameter.


* for anyone thinking “ah, but in 3.x you don’t need arguments to super:

>>> class Sub(Super):
    foo = super().instance_method


Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    class Sub(Super):
  File "<pyshell#6>", line 2, in Sub
    foo = super().instance_method
RuntimeError: super(): no arguments

That’s only true inside instance/class methods!

Leave a Comment