super() doesn't get superclass

Bruno Desthuilliers bruno.42.desthuilliers at wtf.websiteburo.oops.com
Wed Sep 19 06:36:29 EDT 2007


Ben Finney a écrit :
> Bruno Desthuilliers <bruno.42.desthuilliers at wtf.websiteburo.oops.com> writes:
> 
>> Ben Finney a écrit :
>>> Evan Klitzke <evan at yelp.com> writes:
>>>> On Tue, 2007-09-18 at 14:15 +1000, Ben Finney wrote:
>>>>> [the 'super' function] doesn't return the superclass, it returns
>>>>> the next class in the MRO, whether that's a superclass or not.
>>>> The next class in the MRO _is_ a superclass.
>>> [demonstration that the next class in the MRO is not necessarily a
>>> superclass]
>>>
>>> You seem to be saying that now suddenly D *is* a superclass of
>>> A. 
>> I don't see such an assertion in Evan's answer. Chapter and verse
>> ???
> 
> I've trimmed the quoting to make it clearer.
> 
> Evan is claiming that "the next class in the MRO _is_ a superclass",
> apparently by his definition or some other that I've not seen.

The next class in the MRO *is* a superclass of the *instance*. Else it 
wouldn't be in the MRO !-)

> I've shown a fairly simple multiple-inheritance hierarchy where the
> next class in the MRO is not an ancestor of the subject class,

It's an ancestor of the class of the instance on which the method is 
called.

> Either "superclass of A" is equivalent to "ancestor class of A", or
> it's not. I maintain that many programmers will expect that it is, but
> Evan's assertion says otherwise. It can't be both.
> 
>>> That's certainly not what users will think of when they think
>>> "superclass" though.
>> If a class X is in the MRO of call Y, then X is a superclass of Y.

s/call/class/, of course.


> That goes completely against what Alex Martelli told me, which was
> that "superclass" can be thought of as synonymous with "ancestor".

Pardon ???

I repeat: if class X is in the MRO of class Y, then X is a superclass of 
class Y. Which indeed makes X an ancestor of Y.

>> I agree that the documentation for super is somewhat misleading (and
>> obviously wrong),
> 
> Well, that's the first time someone has acknowledged that in this
> thread, so I guess this is something.

OTHO, I don't think anyone here stated that the doc was right !-)

>> but it still *give access to* (at least one of) the superclass(es).
> 
> Only if you allow "some class somewhere in the inheritance tree, even
> one this class never inherited from directly or indirectly" to be in
> the definition of "superclass".

By definition, if the class is in the inheritence tree, then this class 
is inherited from directly or indirectly. FWIW, I've never caught 
super() calling a class that was not in the inheritence tree of the 
instance passed to it... If you noticed such a thing, then by all mean 
fill a bug report.

> I'm arguing that what people mean by "superclass" is "a direct or
> indirect ancestor class", and it's highly misleading to imply that by
> the function name what that's not what the function does.

Please remember that super() is usually called with *2* arguments : the 
class in which the method is defined (let's call this class C), *and* an 
instance. This instance may be an instance of a *subclass* of C. So the 
MRO to consider is the MRO *of the instance*. Else, super would be 
totally useless.

>>>>> After reading the rest of the article, I'm amazed that 'super'
>>>>> as currently implemented is in Python at all.
>> If you have a better solution for handling multiple inheritence,
>> please share with us.
> 
> My concern is to at least not *directly mislead* the programmer
> through a badly-named

Or badly documented

 >  function

class. super is not a function, it's a class.

> If 'super' can invoke a non-superclass

super won't never "invoke" anything that's not in the MRO of the 
*instance* passed to it.

> — if instead it gets "the next class in the MRO" — then this is at the
> least badly-named.

Possibly, but this is another point.

>> FWIW, after all the articles I've read explaining why Python is
>> badly designed, badly implemented, and totally flawed, I do wonder
>> why this language exists at all !-)
> 
> In most of those arguments I'm firmly on the side of the Python
> designers. Not on this one.

Well, I understand that you disagree with both the documention and the 
name of super. As far as I'm concerned, the mere fact that this 
discussion happens is probably a sign that there's something to be fixed 
here - at least wrt documentation, possibly wrt/ naming. But the 
*feature* by itself is certainly something we do want to keep, whatever 
some may argue.

>>> I don't want to break the inheritance chain. I want the
>>> superclass,
>> A soon as you have either multiple inheritence and/or an inheritence
>> tree with depth > 1, there's no such thing as "the" superclass. wrt/
>> your exemple, object, A, B, C and D are *all* superclasses of E.
> 
> Yes, they are. But my example was not "get the superclass of E", but
> "get the superclass of A".

You wrote:

"""
If I define a class hierarchy as follows::

     class A(object): pass
     class B(object): pass
     class C(A): pass
     class D(B): pass

is it true to say that "D is a superclass of A"? No, because they're
entirely unrelated except that they inherit from 'object'. The
superclass of 'A' is 'object'.

How about this:

     class E(C, D): pass

In this instance, the MRO now has D following A; but the superclass of
'A' is still 'object'.
"""

If I understand correctly, your concerns are with the superclass*es* of 
E, not with the superclass of A.

> The *only* ancestor of 'A' in the example is 'object',

Yes.

> so I expect
> "superclass of A" to *always* get 'object'. But that's not what
> happens!

superclass of A is object, no problem. But the next (according to the 
MRO you defined) superclass of an instance of E is not necessarily A...

> Instead, it *sometimes* gets 'object', and *sometimes* gets 'D' —
> depending on who has inherited from a class that isn't even 'A'!
> That's what makes 'super' definitely misnamed,

Badly documented, and (very) possibly (as this whole thread illustrates) 
misnamed...

> and practically
> unusable.

And perfectly usable. At least once you understand what it's for.

>> The next class in the MRO is (usually and AFAICT) the most direct
>> superclass.
> 
> Demonstrably not, in the examples given in
> <URL:http://fuhm.org/super-harmful/>.
> 
>> I wouldn't use such an extreme word as 'madness', but I totally agree
>> that this should be corrected. Care to submit a doc patch ?
> 
> I don't understand what practical uses 'super' is intended for 

There's a whole article on it on python.org:
http://www.python.org/download/releases/2.2/descrintro/#cooperation

The goal is to call the correct "next" method according to MRO. Indeed, 
it could have been name "call_next_method".

> (only
> that they don't seem to match any of my needs),

If all you want is to get at the direct ancestor of the *class* in wich 
a method is defined, the solution is well-known and quite obvious: call 
this class directly. ie:

class A(object):
   def __init__(self):
      print "A.__init__"

class B(object):
   def __init__(self):
      A.__init__(self)
      print "B.__init__"


Note that in this case, you'll get exactly the same result with :

class B(object):
   def __init__(self):
      super(B, self).__init__()
      print "B.__init__"


super is only useful when MI comes in play - which BTW is not that 
common in Python.




More information about the Python-list mailing list