All the while I have been using:
SuperClass.__init__(self, *args, **kwargs)
My reason is that this shows explicitly which superclass is used, especially in the case of multiple inheritance.
However, other codes I came across use
super(MyClass, self).__init__(*args, **kwargs)
instead.
This could become ambigious when it's used in:
class MyClass(SuperClass1, SuperClass2):
def __init__(self, *args, **kwargs):
super(MyClass, self).__init__(*args, **kwargs) #which SuperClass is being used?
I would like to know why this form of calling is widely adopted? Any advantage at all?
In addition to the good answers already posted, here is some additional info:
Old-style classes (those that don't derive from object) have a depth-first method resolution order. Old-style classes call their super classes in the way that you are used to.
New-style classes (those that do derive from object) have a more complicated method resolution order. At the highest level it is akin to breadth first, but is more complex than that. See this page for an excellent explanation. Using "super()" allows new style classes to follow this method resolution order.
If you are using new-style classes, you can still use the old-style of calling super classes and your code will still work. The differences only become apparent for more complicated multiple-inheritance patterns.
The reason that
super
is prefereable for modern (new style) classes is that it allows cooperative multiple inheritance. Here's an example.Note that I didn't do anything to change the
display
method on the superclasses but I got differentdisplay
methods on the subclasses by changing the order in which I arranged the superclasses.BarFoo
andFooBar
have different methods. This is because they have different Method Resolution OrdersThis means that
super
resolves to a different class for each subclass that it's called in. This allows for each overriding method to change a small part of what's going on and still let every other superclass contribute to the method call as long as they're willing to play nicely.For new style classes which inherit from
object
,super
is used.The
__mro__
(method resolution order) attribute of the type lists the method resolution search order used bysuper
.This specifies the ordering for Z. Since it is
Z(X, Y)
,X
is first in the hierarchy. Had it beenZ(Y, X)
,Y
would have preceded overX
.For old style classes,
SuperClass.__init__(self, *args, **kwargs)
is used.UPDATE:
For your question as to which
SuperClass
is being used.First,
First
will be checked to see if it has an__init__
, sinceFirst
comes first in the MRO. Since in this case 'First' doesn't have an__init__
, soSecond
is called. Had there been an__init__
inFirst
, only that would have been called.