Dispatch with multiple inheritance
Nick Vatamaniuc
vatamane at gmail.com
Tue Jul 18 15:48:25 EDT 2006
Michael,
You only need to call the __init__ method of the superclass if you need
to do something special during initialization. In general I just use
the SuperClass.__init__(self,...) way of calling the super class
constructors. This way, I only initialize the immediate parents and
they will in turn call the init method of their parents and so on.
super() is probably the a better way to do things but I find
SuperClass.__init__(self, ...) more clear. For example your code would
be:
-------------------------------
class A (object):
def __init__(self):
print "cons A"
class B (object):
def __init__(self):
print "cons B"
class C (A):
def __init__(self):
A.__init__(self)
print "cons C"
class D (B):
def __init__(self):
B.__init__(self)
print "cons D"
class E(D,C):
def __init__(self):
C.__init__(self)
D.__init__(self)
print "cons E"
e=E()
----------------------------------
Output should be:
cons A
cons C
cons B
cons D
cons E
In general note that __init__ is NOT a constuctor it is an initializer
(therefore the name __init__ as opposed to __constr__ or __new__). The
object is constructed by Python already and is given to init method as
the 'self' argument. The construction can also be customized inside the
__new__ magic method, but normally you don't even need to know about
__new__.
Hope this helps,
Nick V.
Michael J. Fromberger wrote:
> Consider the following class hierarchy in Python:
>
> class A (object):
> def __init__(self):
> print "cons A"
>
> class B (object):
> def __init__(self):
> print "cons B"
>
> class C (A):
> def __init__(self):
> super(C, self).__init__()
> print "cons C"
>
> class D (B):
> def __init__(self):
> super(D, self).__init__()
> print "cons D"
>
> Now, suppose I would like to define a new class as follows:
>
> class E (C, D):
> ...
>
> In the constructor for E, I would like to invoke the constructors of
> both parent classes. The correct way to do this seems to be exemplified
> by the following:
>
> class E (C, D):
> def __init__(self):
> super(E, self).__init__() # calls C constructor
> super(A, self).__init__() # calls D constructor (**)
> print "cons E"
>
> This works, but I find it somewhat troubling. It seems to me that one
> should not have to "know" (i.e., write down the names of) the ancestors
> of C in order to dispatch to superclass methods in D, since C and D
> share no common ancestors south of object.
>
> Is there a better (i.e., more elegant) way to handle the case marked
> (**) above?
>
> Curious,
> -M
>
> --
> Michael J. Fromberger | Lecturer, Dept. of Computer Science
> http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
More information about the Python-list
mailing list