[Tutor] How to access an instance variable of a superclass from an instance of the subclass?

Alan Gauld alan.gauld at yahoo.co.uk
Thu Feb 23 05:09:27 EST 2017


On 23/02/17 04:25, boB Stepp wrote:
> I am trying to wrap my head around the mechanics of inheritance in
> Python 3.  I thought that all attributes of a superclass were
> accessible to an instance of a subclass. 

For class attributes that happens automatically.

>>> class A:
	a = 'A'
	def __init__(self):
		self.aa = 'aa'

		
>>> class X(A): pass

>>> x = X()
>>> x.a
'A'
>>> x.aa
'aa'

Notice that both the class and instance variables
are inherited. That's because there is no
__init__() in X so the inherited A.__init__()
is called.

Now, if we add an init to the subclass:

>>> class B(A):
	b = 'B'
	def __init__(self):
		self.bb='bb'

		
>>> b = B()
>>> b.a
'A'
>>> b.bb
'bb'
>>> b.aa
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    b.aa
AttributeError: 'B' object has no attribute 'aa'

We get the scenario you found. (But with the additional fact
that B can access A's class variable 'a')

The B.__init__() is called, but it does not create an aa instance
variable. To do so we need to call the superclass constructor:

>>> class C(A):
	c = 'C'
	def __init__(self):
		super().__init__()
		self.cc = 'cc'

		
>>> c = C()
>>> c.a
'A'
>>> c.aa
'aa'
>>> c.cc
'cc'
>>> c.bb
Traceback (most recent call last):
  File "<pyshell#32>", line 1, in <module>
    c.bb
AttributeError: 'C' object has no attribute 'bb'
>>>

Now C can access cc and aa (as well as a), but
not B.bb of course because its not in the inheritance line.

There is no real magic(*) going on here.
When you call SomeClass() the SomeClass.__new__() method
gets called which is usually the one defined in object.
That method results in __init__() getting called. The
usual method lookup applies, the first init() found will
be executed. If it doesn't explicitly call the
superclass init then that method will never be
called.

(*)Actually its not quite this straightforward because
meta-classes are involved in the invocation of new()
and it all gets a bit mind-bending. But as a concept
you can stick with new() as the constructor calling
init() as the initializer and both being subject
to the usual method resolution rules.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list