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?
解决方案
The reason that super is prefereable for modern (new style) classes is that it allows cooperative multiple inheritance. Here's an example.
>>> class Foo(object):
... def display(self):
... print "In Foo"
...
>>> class Foo2(Foo):
... def display(self):
... print "In Foo2"
... super(Foo2, self).display()
... print "Back in Foo2"
...
>>> class Bar(Foo):
... def display(self):
... print "In Bar"
... super(Bar, self).display()
... print "Back in Bar"
...
>>> class FooBar(Foo2, Bar):
... pass
...
>>> FooBar().display()
In Foo2
In Bar
In Foo
Back in Bar
Back in Foo2
>>> class BarFoo(Bar, Foo2):
... pass
...
>>> BarFoo().display()
In Bar
In Foo2
In Foo
Back in Foo2
Back in Bar
Note that I didn't do anything to change the display method on the superclasses but I got different display methods on the subclasses by changing the order in which I arranged the superclasses. BarFoo and FooBar have different methods. This is because they have different Method Resolution Orders
>>> BarFoo.__mro__
(, , , , )
>>> FooBar.__mro__
(, , , , )
This 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.