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