[Python-ideas] [Python-Dev] python and super

Mike Graham mikegraham at gmail.com
Fri Apr 15 20:00:17 CEST 2011


On Fri, Apr 15, 2011 at 12:42 PM, Carl Meyer <carl at oddbird.net> wrote:
> ...
> Consider these classes:
>
> class UncooperativeBase:
>    def method(self):
>        # look Ma, no super() call!
>        return ["UncooperativeBase"]
>
>
> class OtherBase:
>    def method(self):
>        return ["OtherBase"] + super().method()
>
>
> class Child(UncooperativeBase):
>    def method(self):
>        return ["Child"] + super().method()
>
>
> class GrandChild(Child, OtherBase):
>    def method(self):
>        return ["GrandChild"] + super().method()
>
>
> Currently, OtherBase.method() is never called, because
> UncooperativeBase.method() breaks the super() chain. Any proposal to
> have super() ensure that OtherBase.method() is called needs to explain
> what exactly happens to its return value. This would normally be handled
> explicitly by UncooperativeBase, since it would call super() and do
> something with the return value. But with the explicit chain broken, you
> end up with two different chains, and at some point their return values
> would need integrating.
>
> Carl

I feel like you're implying this would be fixed by having
UncooperativeBase call super().method(), but this would not make
working code. _It's the base class's responsibility *not* to call
super._

If UncooperativeBase called super() and we called
GrandChild().method(), then we would call our three superclasses's
method methods and object's. the problem is that object doesn't even
HAVE a method method, so we'll get an error. (For the very common
example of __init__, object *IS* the shared superless base class with
the method we want, but we need our own shared superless base class
for arbitrary methods.)

This isn't a problem I know a technical solution to—we can't have two
independent base classes with the same method. If they are related to
each other, they need to share a base class that probably doesn't do
anything exciting. If they're truly unrelated, then we don't want to
be calling them interchangeably in the MRO and we need to give them
different names, perhaps using a proxy class with one that calls into
the other.

Another solution that is much cleaner is to use composition for one or
both of the classes involved. This only works if these are concrete
classes, obviously, but gets us tons of benefits. It's not at all
complicated to decide what needs to be called when, change names, or
pick-and-choose what functionality to re-use.

Mike



More information about the Python-ideas mailing list