Multiple inheritance, super() and changing signature

Steven D'Aprano steve at pearwood.info
Fri Jun 3 22:51:42 EDT 2016


On Sat, 4 Jun 2016 11:06 am, Gregory Ewing wrote:

> Nagy László Zsolt wrote:
>> I do not use diamond shapes in my hierarchy, I guess that does not
>> affect me. I may be wrong.
> 
> If there are no diamonds, 

In Python 3, or Python 2 with new-style classes, there are ALWAYS diamonds
when you use multiple inheritance.


> there is no need to use super. 

Except then you are precluding others from integrating your classes into
their class hierarchies.


> Explicit inherited method calls, done correctly, will
> work fine.
> 
> The only downside is that if your inheritance hierarchy
> changes, you need to review all your inherited calls
> to make sure they're still correct.
> 
> The use of super to address that issue seems attractive.
> However, super is only applicable if some rather stringent
> requirements are met:
> 
> 1. All the methods must have compatible signatures.
> 
> 2. Except for 3 below, all classes participating in the
> hierarchy must use super for a given method if any of
> them do, including any future subclasses.
> 
> 3. There must be a class at the top of the hierarchy
> that does *not* make super calls, to terminate the chain.

Normally that will be object.

Sometimes you need to prevent messages reaching object. But to my mind,
that's a code-smell, and indicates you're doing something wrong.

"Something wrong" may be multiple inheritance itself. There is a reason why
most languages don't allow MI at all, or only allow a much restricted
subset of it, in the form of mixins or traits.

And in fact, even using inheritance alone is harder than it seems.
Composition is just as powerful and usually easier to work with.

[...]

> If you can't satisfy *all* of these reqirements, then
> you can't use super. Sorry, but that's just the way
> super is.

If you can't use super, then chances are you can't use *anything*, including
manual calls to superclass methods. There's nothing magical about the use
of super itself. If you have problems with super, then you have two
choices:

(1) Manually walk the MRO making the same calls that super would have made,
in which case you'll have the same problems super did.

(2) DON'T walk the MRO making the same calls that super would have made, in
which case you will have all the problems that super solves. Namely, you
will either miss calling superclass methods, or you will call them two many
times.


In a straight linear single inheritance class hierarchy, walking the MRO is
trivial whether you use super or not, but not using super restricts you to
never using super. But in MI, not using super almost certainly means you're
doing it wrong.

(If you're lucky, you can get away with it if the methods you fail to call
aren't needed, or do nothing, and the methods you call twice are harmless.)




-- 
Steven



More information about the Python-list mailing list