From: Steven D'Aprano on
On Sun, 25 Jul 2010 13:58:00 +1200, Gregory Ewing wrote:

> Lacrima wrote:
>
>> But what if SuperClass1 is from third party library?
>
> If it hasn't been designed for super(), then you can't use super() with
> it.
>
> super() only works when *every* class in the hierarchy has been designed
> with it in mind.


That incorrect. You can certainly use super() with classic classes in the
hierarchy, and super() didn't even exist when they were created.


>>> class Parent:
.... def method(self, arg):
.... return repr(arg)
....
>>> class Classic(Parent):
.... def method(self, arg):
.... return "argument was %s" % Parent.method(self, arg)
....
>>> class New(object, Classic):
.... def method(self, arg):
.... return super(New, self).method(arg).upper()
....
>>> x = New()
>>> x.method('spam')
"ARGUMENT WAS 'SPAM'"


The problem isn't super(), and people who give glib advise "don't use
super()" are just compounding the problem. The problem is with multiple
inheritance where methods have different method signatures. If you don't
change the method signatures, super() will work fine.

Advising people not to use super() might make people feel virtuous, but
it doesn't do anything to help the reader write non-buggy MI hierarchies.
It pushes the effort of dealing with multiple inheritance onto them,
forcing them to re-implement the MRO, probably badly. Can you re-
implement the C3 algorithm? Have you even heard of it? If you answer No
to either of those questions, chances are high that trying to deal with
the MRO manually will lead to worse bugs than using super().

Should you use super()?

1. If you're doing multiple inheritance with metaclasses, you MUST use
super().

2. If you're using single inheritance only, and never modify method
signatures, there is no reason not to use super().

3. If you're using mixins, you should use super().

4. If you never modify method signatures, then you should use super().

5. If you do modify method signatures, you shouldn't do that (except
possibly in constructors, and even there only cautiously). But if you do
it anyway, then you should use super() *except* in the methods where you
modify the signature.

6. If you don't use super(), chances are that your class hierarchy is
still buggy, but instead of failing loudly and noisily with an exception,
it's silently giving the wrong results.

7. If you can avoid multiple inheritance in favour of another technique
(such as composition), you should strongly consider that.



--
Steven