jfj wrote:
> As for the case where the users of the library want to subclass, I don't> see a problem.??They?know?they?must?subclass?from?class?XXX?and?so?they> call XXX.__init__ to construct it.
I was thinking of
class Child(Father, Mother):
pass
where Father and Mother have a common base class Parent. That would be
initialized twice:
>>> class Parent(object):
... def __init__(self):
... print "parent"
...
>>> class Father(Parent):
... def __init__(self):
... print "father"
... Parent.__init__(self)
...
>>> class Mother(Parent):
... def __init__(self):
... print "mother"
... Parent.__init__(self)
...
>>> class Child(Father, Mother):
... def __init__(self):
... print "child"
... Father.__init__(self)
... Mother.__init__(self)
...
>>> Father()
father
parent
<__main__.Father object at 0x402ad66c>
>>> Mother()
mother
parent
<__main__.Mother object at 0x402ad38c>
>>> Child()
child
father
parent
mother
parent # <-- the culprit: parent initialized a second time
<__main__.Child object at 0x402ad66c>
You have several options now:
- Write __init__() in such a way that calling it twice does no harm
- Ensure that it is only called once by adding a self.initialized flag
- Document that a user class may not inherit from both Father and Mother
but the best is IMO
- let super() do the work
> In the case of Parent diamond inheritance, super() can avoid calling> the __init__ of parent twice???How?
That's the best part -- it's automatic:
>>> class Parent(object):
... def __init__(self):
... print "parent"
... super(Parent, self).__init__()
...
>>> class Father(Parent):
... def __init__(self):
... print "father"
... super(Father, self).__init__()
...
>>> class Mother(Parent):
... def __init__(self):
... print "mother"
... super(Mother, self).__init__()
...
>>> class Child(Father, Mother):
... def __init__(self):
... print "child"
... super(Child, self).__init__()
...
>>> Father()
father
parent
<__main__.Father object at 0x402ad38c>
>>> Mother()
mother
parent
<__main__.Mother object at 0x402ad3cc>
>>> Child()
child
father
mother
parent # <-- parent only once
<__main__.Child object at 0x402ad38c>
That was a lot of dull code -- but you asked :-)
Seriously, I think super() scales better in a scenario with multiple
inheritance, though I won't start a holy war about the issue.
Peter