Builtn super() function. How to use it with multiple inheritance? And why should I use it at all?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sat Jul 24 23:48:27 EDT 2010


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



More information about the Python-list mailing list