Invoke a superclass method from a subclass constructor

Kayode Odeyemi dreyemi at gmail.com
Sun Sep 11 13:17:27 CEST 2011


On Sun, Sep 11, 2011 at 11:41 AM, Thomas Jollans <t at jollybox.de> wrote:

> 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
> '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+?


> 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.

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.

>
>  - Thomas
> --
> http://mail.python.org/mailman/listinfo/python-list
>



-- 
Odeyemi 'Kayode O.
http://www.sinati.com. t: @charyorde
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20110911/ee190813/attachment.html>


More information about the Python-list mailing list