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