calling upper constructor

Alex Martelli aleax at aleax.it
Fri Feb 1 12:36:07 EST 2002


Courageous wrote:

>>class abc(base):
>>   def __init__(self):
>>     # how do I call base's init here?
> 
> class derive (base):
>     def __init__ ( self, x ):
>         base.__init__( self, x )

This correctly answers the literal question as posed.

However, the intention behind the question may be to
"upcall to the 'right' superclass constructor".  Multiple
inheritance means that base.__init__ may not be the
'right' superclass-constructor to call at this point, e.g.:

class base:
    def __init__(self):
        print 'base init'
 
class derive1(base):
    def __init__(self):
        print 'derive1 init'
        base.__init__(self)
 
class derive2(base):
    def __init__(self):
        print 'derive2 init'
        base.__init__(self)
 
class doublyderive(derive1, derive2):
    def __init__(self):
        print 'doublyderive init'
        derive1.__init__(self)
        derive2.__init__(self)
 
dd = doublyderive()

[alex at lancelot alex]$ python dd.py
doublyderive init
derive1 init
base init
derive2 init
base init

This leads to running base init twice -- sometimes
innocuous, sometimes dangerous.  As you can see,
if derive1 and derive2 each call base.__init__ directly,
there's really no way doublyderive can ensure each
of its direct bases is initialized but the bases' base is
only initialized once.

Python 2.2 to the rescue!  Here's how you can code
this in Python 2.2:

class base(object):
    def __init__(self):
        print 'base init'
 
class derive1(base):
    def __init__(self):
        print 'derive1 init'
        super(derive1, self).__init__()
 
class derive2(base):
    def __init__(self):
        print 'derive2 init'
        super(derive2, self).__init__()
 
class doublyderive(derive1, derive2):
    def __init__(self):
        print 'doublyderive init'
        super(doublyderive, self).__init__()
 
dd = doublyderive()


[alex at lancelot alex]$ python dd.py
doublyderive init
derive1 init
derive2 init
base init


Voila -- thanks to the magic of super(), every initializator
runs once, and only once.  Note that base needs to derive
from object (directly or indirectly) for this to work, i.e., it
must be a "new-style class"; a classic class, one without
such derivation, closely mimics 2.1's semantics and thus,
alas, cannot be used in a super() call.


Alex




More information about the Python-list mailing list