super() and multiple inheritance failure

Chris Rebert clp2 at rebertia.com
Fri Sep 25 23:15:54 EDT 2009


On Fri, Sep 25, 2009 at 7:36 PM, Steven D'Aprano
<steve at remove-this-cybersource.com.au> wrote:
> I don't understand why I'm getting the following behaviour when using
> super() with multiple inheritance. The following is a minimal example
> demonstrating the behaviour.
>
> I have a diamond class hierarchy as follows:
>
>  o
>  |
>  B
> / \
> P  N
> \ /
>  M
>
> where:
> o = object
> B = BaseClass
> P = PClass
> N = NClass
> M = MyClass
>
> Inside MyClass().method(n), I dispatch to either NClass.method() or
> PClass.method() depending on the value of the argument n. The correct
> class is called, but then the *other* class method is called as well.
> E.g. this is what I expect:
>
> MyClass().method(2)
> ->  calls PClass.method
>    -> calls BaseClass.method
>
> but this is what I get:
>
> MyClass().method(2)
> ->  calls PClass method
>    ->  calls NClass.method
>        -> calls BaseClass.method
>
>
> and similarly for negative arguments, swapping PClass and NClass.
>
> First off, is this the expected behaviour? I seems strange to me, can
> somebody explain why it is the nominally correct behaviour?

Pretty darn sure it's expected. super() follows the MRO, which in this
case is M, P, N, B, o; thus, the super() of an M instance from a P
method is indeed N.
This would normally be useful as one typically wants to call the
"parent" methods of all ancestor classes for which the method is
defined, rather than picking-and-choosing as MyClass.method() does. To
put it another way, if super() didn't act like it does, other people
would complain about N.method() getting skipped (e.g. "What then was
the point of my subclassing N if its methods don't get called?").

Remember that super() is sorta misnamed; Dylan's equivalent is named
"next-method" (Dylan is where Python cribbed much of its multiple
inheritance system from).

Cheers,
Chris
--
http://blog.rebertia.com



More information about the Python-list mailing list