I\'m pretty much new in Python object oriented programming and I have trouble
understanding the super()
function (new style classes) especially when it comes to
I wanted to elaborate the answer by lifeless a bit because when I started reading about how to use super() in a multiple inheritance hierarchy in Python, I did't get it immediately.
What you need to understand is that super(MyClass, self).__init__()
provides the next __init__
method according to the used Method Resolution Ordering (MRO) algorithm in the context of the complete inheritance hierarchy.
This last part is crucial to understand. Let's consider the example again:
#!/usr/bin/env python2
class First(object):
def __init__(self):
print "First(): entering"
super(First, self).__init__()
print "First(): exiting"
class Second(object):
def __init__(self):
print "Second(): entering"
super(Second, self).__init__()
print "Second(): exiting"
class Third(First, Second):
def __init__(self):
print "Third(): entering"
super(Third, self).__init__()
print "Third(): exiting"
According to this article about Method Resolution Order by Guido van Rossum, the order to resolve __init__
is calculated (before Python 2.3) using a "depth-first left-to-right traversal" :
Third --> First --> object --> Second --> object
After removing all duplicates, except for the last one, we get :
Third --> First --> Second --> object
So, lets follow what happens when we instantiate an instance of the Third
class, e.g. x = Third()
.
Third.__init__
executes.
Third(): entering
super(Third, self).__init__()
executes and MRO returns First.__init__
which is called.First.__init__
executes.
First(): entering
super(First, self).__init__()
executes and MRO returns Second.__init__
which is called.Second.__init__
executes.
Second(): entering
super(Second, self).__init__()
executes and MRO returns object.__init__
which is called.object.__init__
executes (no print statements in the code there)Second.__init__
which then prints Second(): exiting
First.__init__
which then prints First(): exiting
Third.__init__
which then prints Third(): exiting
This details out why instantiating Third() results in to :
Third(): entering
First(): entering
Second(): entering
Second(): exiting
First(): exiting
Third(): exiting
The MRO algorithm has been improved from Python 2.3 onwards to work well in complex cases, but I guess that using the "depth-first left-to-right traversal" + "removing duplicates expect for the last" still works in most cases (please comment if this is not the case). Be sure to read the blog post by Guido!