Builtn super() function. How to use it with multiple inheritance? And why should I use it at all?
steve at REMOVE-THIS-cybersource.com.au
Sun Aug 1 09:38:44 CEST 2010
On Sat, 31 Jul 2010 13:29:25 +0000, Brian Victor wrote:
> Steven D'Aprano wrote:
>> On Sat, 31 Jul 2010 14:25:39 +1200, Gregory Ewing wrote:
>>> Steven D'Aprano wrote:
>>>> / \
>>>> C B
>>>> \ /
>>>> / \
>>>> E F
>>>> Yes, a super call might jog left from C to B, but only when being
>>>> called from one of the lower classes D-F. That's still an upwards
>>>> call relative to the originator, not sidewards.
>>> But it's not an upward call relative to the class mentioned in the
>>> super() call, which is why I say it's misleading.
>> Which class would that be?
>> I think I'm going to need an example that demonstrates what you mean,
>> because I can't make heads or tails of it. Are you suggesting that a
>> call to super(C, self).method() from within C might call
> Yes, it would.
Right, now I see what you mean. I don't have a problem with that
behaviour, it is the correct behaviour, and you are making the call from
D in the first place, so it *must* call B at some point.
If you initiate the call from C instead:
then B is not in C's MRO, and does not get called. This is the case I was
I admit it did surprise me the first time I saw the example you gave.
Hell, it *confused* me at first, until I realised that self inside the
method isn't necessarily an instance of C, but could be an instance of a
subclass of C (in this case, D), and then it was "Well duh, how obvious!"
That's no different from a classic-style call to a superclass:
# inside class C(B):
Inside B, method() gets called with an instance of C as self.
Bringing it back to super(), since super(C, self) gets a D instance as
argument, the MRO it looks at is D's MRO, and it all just works. I think
the docs could make that a little more clear, but then, given how non-
cooperative inheritance works exactly the same way, there's a good
argument for saying the docs don't need to be changed at all. If the
behaviour is confusing for super(), then it's confusing without super()
See Guido's tutorial on cooperative multitasking for more detail:
> Since the idea of super() as I understand it is to make sure every class
> in an object's hierarchy gets its method called, there's really no way
> to implement super() in a way that didn't involve a non-superclass being
> called by some class's super() call.
You're reading the super() signature wrong.
shouldn't be interpreted as "call C's superclasses from self". It means
"starting just after C in the MRO, call self.__class__'s superclasses".
super() never calls a non-superclass. If it did, it would be a huge bug,
and inheritance would break.
More information about the Python-list