Invoke a superclass method from a subclass constructor

Thomas Jollans t at
Sun Sep 11 12:41:08 CEST 2011

On 11/09/11 10:18, Kayode Odeyemi wrote:
> Hello friends,
> An instance of my subclass doesn't invoke its superclass method, except
> when it is referenced
> directly. 
> Here is what I mean:
>>>> class A(object):
> ...     def log(self, module):
> ...             return str('logged')
> ...
>>>> class B(A):
> ...     def __init__(self, module):
> ...             self.module = A().log(module)
> ...
>>>> c = B('system')
>>>> # I expect 'logged' to be printed here
>>>> print c.log('system') # why do I have to do this?
>>>> 'logged'
> Why do I have to make a call to c.log before log() method can be invoked?
> My reasoning is such that since I have passed the log() method to B's
> constructor, an instance
> of B should invoke A's log() method.
> What could I be missing in class A or B to have this working as expected?

It is working:

>>> class A(object):
...     def log (self, module):
...         return str ('logged')
>>> class B(A):
...     def __init__(self, module):
...         self.module = A().log(module)
>>> c = B('system')
>>> c.module

In B's constructor, you create a new instance of A (a pointless
excersise - you already have an instance of A, "self"), call its log()
method, and store the return value of that method in the attribute "module".

This is how you'd usually call a superclass's method:

>>> class B2(A):
...     def __init__(self, module):
...         # This is the way to call a superclass method:
...         self.log (module)
>>> c2 = B2 ('system')

That's what inheritance is. If B is derived from A, any B *is* also an A.

Now, something that might be closer to what you're actually heading for,
to think about. Please note that I'm using Python 3: explicitly deriving
a class from object is no longer necessary, and the "super" function is
now simpler. If you want to use Python 2, I'll leave looking up how to
use its "super" function as an excersise to the reader.

>>> class ModuleLogger:
...     def __init__(self, module):
...         self.module = module
...         print ('module logged: {0}'.format (module))
>>> class Foo (ModuleLogger):
...     def __init__(self, module):
...         # calling a superclass constructor here, in Python 3 syntax:
...         super().__init__(module)
>>> f = Foo ('system')
module logged: system

Using super() is always necessary when calling a superclass' method that
is also implemented in the subclass - self.__init__ would just invoke
the Foo constructor, you need super() to get to the ModuleLogger

 - Thomas

More information about the Python-list mailing list