Python's super (considered harmful)

Saturday 29 September 2007

I have long been confused by the super() function in Python. It's used to call a method on the base class of an object. Why not simply invoke the base class directly, like we used to?

class Derived(Base):
    def __init__(self):
        super(Derived, self).__init__()     # Right
        # Base.__init__(self)               # WRONG!

And shouldn't the argument to super be Base, not Derived? It doesn't seem to make any sense. I finally was truly confused when deriving a class from two base classes. If I only have one call to super, how do I make sure that both base class methods get called? Poking around for an answer, I finally found a good explanation of what super() is for. Ironically, it is a polemic about why super() is no good: Python's Super Considered Harmful. Skip the part about Dylan, and read about the Python, and finally understand...

It turns out multiple inheritance is where everything is cleared up, and where the problems are that super() is actually solving. In a strictly single-inheritance world, the old style of calling the base class methods works fine. In multiple inheritance, you can't actually predict what class you'll call.

tagged: » 4 reactions

Comments

[gravatar]
Manuzhai 10:12 AM on 29 Sep 2007

By the way, super will be all different in Python 3.0. I don't remember exactly what was changed because I usually have little need for it, but you may want to check it out.

[gravatar]
David St.Germain 10:23 AM on 29 Sep 2007

Yeah, Ned. duh. Welcome to 2001...

[gravatar]
Jay P. 10:54 AM on 29 Sep 2007

The simple answer I always give to people, is that if you happen to change the Base class, you don't need to worry about forgetting to change the parent call in __init__. This is also why super() takes the Derived class as the argument, not the base class.

At least, that's what I tell people :)

[gravatar]
Kevin Dangoor 11:41 AM on 1 Oct 2007

Python 3.0 does make it a bit prettier:

>>> class A:
... def hello(self):
... print("Hi")
...
>>> class B(A):
... def hello(self):
... super().hello()
... print("There")
...
>>> b = B()
>>> b.hello()
Hi
There
>

Add a comment:

name
email
Ignore this:
not displayed and no spam.
Leave this empty:
www
not searched.
 
Name and either email or www are required.
Don't put anything here:
Leave this empty:
URLs auto-link and some tags are allowed: <a><b><i><p><br><pre>.