[Tutor] What is super for?

Steven D'Aprano steve at pearwood.info
Tue Jun 29 02:28:39 CEST 2010


On Tue, 29 Jun 2010 02:15:00 am Adam Bark wrote:

> I can't figure out how super(C, self).__init__() is any better than
> C.__init__(self), is there a preference? Does super do something
> special?

You've written that slightly wrong. You write the name of the *parent* 
class in the direct call to the method, and the name of the *current* 
class in the call to super:

class MyClass(C):
    def __init__(self):
        super(MyClass, self).__init__()
        # or C.__init__(self)


super() does a lot, but remember it only works with new-style classes.


Consider a class with multiple inheritance:

class MyClass(C, D):
    def f(self, *args):
        do_something()
        # now need to inherit behaviour from the super-classes

The question is, how do we write method f()?

    def f(self, *args):
        do_something()
        C.f(self, *args)
        D.f(self, *args)

But that's not right, because C might not have method f. Or D might not 
have it. Or they might both have it. 

Or neither C nor D have the method, and *both* inherit it from the same 
parent class higher up the hierarchy, B. If you manually call C.f and 
D.f, you end up calling B.f *twice*. Oops.

Even if C and D don't share the same parent class, they might inherit 
from a chain of classes, any of which defines f. Working out which 
method f to call can be complicated.

super() handles all that complication for you. You just write:

    def f(self, *args):
        do_something()
        super(MyClass, self).f(*args)

and it works out which parent classes to call in which order.

Now, right about now you're probably thinking that since you don't use 
multiple inheritance, you don't care about super. Fair enough. But 
consider somebody who imports your class to inherit from them. They 
might be using multiple inheritance, or they might not be. If you use 
super(), then your class will work correctly for them regardless of 
whether they have multiple or single inheritance. But if you call the 
parent class manually, your class will *only* work with single 
inheritance.

You can find lots more about super and multiple inheritance on the web, 
both for and against. Mostly against in the Python world. I have read 
them, so you don't have to, and my summary is:

* Don't use multiple inheritance.
* If you have to use multiple inheritance, make sure you *really* 
  have to.
* Whether you use multiple inheritance or not, use super() so that 
  those brave or foolish souls who do can inherit from you.
* Use super() consistently, and document that you use it as part of
  your class' external interface.
* Never call super() with anything but the exact arguments you 
  received, unless you're a guru.

There is a provocative article called "Python's Super Considered 
Harmful". Despite the title, if you read the whole article you discover 
that the author doesn't actually recommend *against* super at all.

http://fuhm.net/super-harmful/

This thread on the Python-Dev mailing list discusses the above article:

http://mail.python.org/pipermail/python-dev/2005-January/050656.html

And here are some links from Michele Simionato on why mixins and 
multiple inheritance should be avoided unless you really, really need 
it, and how to avoid needing it:

http://www.artima.com/weblogs/viewpost.jsp?thread=246341
http://www.artima.com/weblogs/viewpost.jsp?thread=246483
http://www.artima.com/forums/flat.jsp?forum=106&thread=237121
http://www.artima.com/forums/flat.jsp?forum=106&thread=246488


-- 
Steven D'Aprano


More information about the Tutor mailing list