Invoke a superclass method from a subclass constructor

Thomas Jollans t at jollybox.de
Sun Sep 11 13:32:52 CEST 2011


On 11/09/11 13:17, Kayode Odeyemi wrote:
> On Sun, Sep 11, 2011 at 11:41 AM, Thomas Jollans <t at jollybox.de
> <mailto:t at jollybox.de>> wrote:
> 
>     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
>     'logged'
> 
> Why do you have to do c.module? I'm expecting an output just by creating
> an instance of B.
> Could this be a limitation in Py2+?
>  

I believe I already answered that question. You quoted my answer
directly below your question:

> 
>     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
>     >>>
> 
> I'm on Py2.7.
> 
> class ModuleLogger is not the same as class A (the one I'm using as an
> example). I need the log()
> method to be an instance of class A. I don't want it declared in class A
> constructor because I don't
> want to have access to it when class A is instantiated.

Then do it differently. I was merely offering an example that I hoped
might help you acheive your goals.

> 
>     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
>     constructor.
> 
> 
> Well, I did try using super(), but I got this: 
>>>> class B(A):
> ...     def __init__(self, module):
> ...             super(A, self).log('system')
> ...
>>>> c = B('module')
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 3, in __init__
> AttributeError: 'super' object has no attribute 'log'
> 
> I hope a reader on Py2+ can help with this.

If you'd read my previous response carefully, you'd know that in this
case, you don't need super(), and you'd also know how to use the
superclass' method.





More information about the Python-list mailing list