Tue 21 Jan 2014
The Python programming language added the super() type back in version 2.2. For some reason, it’s still a topic that a lot of beginners don’t understand. One of my readers recently asked me about it and since I don’t really use it, I decided to do some research in the hopes of understanding its usage myself so I could explain what super is and why you would use it. We’ll spend some time looking at various people’s definitions of super and then look at some examples to try to figure this out.
What is super?
Here is what the official Python documentation has to say about super: Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped.
A couple of years ago, Cody Precord released a wxPython Cookbook in which he used super all the time. That brought up the discussion of super on the wxPython mailing list for several weeks. Let’s take a look at some of those threads.
Robin Dunn, creator of wxPython, stated the following: In most cases there isn’t any difference. In cases where you have multiple inheritance, the super() helps to ensure that the proper
method resolution order (MRO) is followed when moving up the inheritance tree. He then linked to StackOverflow.
In another thread, Tim Roberts (a very experienced Python programmer) had the following to say:
It is a “shortcut” to allow you to access the base class of a derived class, without having to know or type the base class name. For example:
class This_is_a_very_long_class_name(object): def __init__(self): pass class Derived(This_is_a_very_long_class_name): def __init__(self): super(Derived,self).__init__() #1 This_is_a_very_long_class_name.__init__(self) #2
Those last two lines are two ways of spelling the same thing. Besides just the spelling, this also allows you to change the base class without having to go through all of your code and replace the base class name. C++ programmers often do this with a typedef in their derived classes.
So what I get from these 2 statements is that super is important when you’re doing multiple inheritance, but otherwise it doesn’t really matter whether you use it or not. If you scroll down through that second thread, you’ll see a couple of examples from both Robin Dunn and Tim Roberts that help illustrate when using super can be helpful. Let’s take a look at Mr. Dunn’s example.
Note: The following code uses Python 2.x syntax for super. In Python 3, you don’t need to pass the class name or even self!
class A(object): def foo(self): print 'A' class B(A): def foo(self): print 'B' super(B, self).foo() class C(A): def foo(self): print 'C' super(C, self).foo() class D(B,C): def foo(self): print 'D' super(D, self).foo() d = D() d.foo()
If you run this code, you will get the letters “DBCA” (one letter per line) as output. As Robin Dunn points out in the thread, “A” is only printed once even through two classes derive from it. This is due to the method resolution order (MRO) that is inherent in the new style classes of Python. You can check out the MRO by adding print D.__mro__ underneath the super call in class D’s foo function (note: this only works if the base is derived from object). This StackOverflow entry explains it in more detail. If you want a good read on the subject of MRO, I would recommend the following abstract on Python.org: http://www.python.org/download/releases/2.3/mro/.
Now you may be thinking that this example is not only abstract, but not of much use and you would be quite right. Which is why it is worth doing some additional digging online to find other examples. Fortunately, I recalled seeing an article by Raymond Hettinger on super a couple of years ago. He is a core Python developer and speaks at PyCon regularly. Anyway, his article gives several good real-life examples of using super to add new features to sub-classes. I highly recommend checking out his article as it goes a long ways towards explaining super in an applicable way. Even the Python documentation for super() links to his article!
Here’s a pretty good list on the topic:
- Official Python documentation about super
- Raymond Hettinger’s ruminations on super
- Python’s Super is nifty, but you can’t use it
- StackOverflow: Understanding Python Super
- StackOverflow: How to use super in Python
- Understanding Python’s super
- How to use super() effectively — Python 2.7 version (Python recipe)
- Zed Shaw’s comments on super() in his Learn Python the Hard Way online book
- Method Resolution Order (MRO) abstract