Difference of calling inherited methods in subclass?
For Python 2.5 and later, with new style class, what's the difference of the following code snippets for invoking inherited methods in a subclass?
class A(object):
def foo(self):
pass
class B(A):
def __init__(self):
self.foo()
class C(A):
def __init__(self):
super(C, self).f开发者_Python百科oo()
As long as you are dealing with single inheritance classes like the example you gave,
there is not much difference. In either case, python uses the method resolution order(mro),
(which you can examine by printing C.__mro__
) to find out the first occurance of the method
foo. These both resolve to your base class, A's, foo implementation.
However, things become interesting when you have multiple inheritance. Look at the following example:
class W(object):
def foo(self):
print "W"
class X(W):
def foo(self):
#super(X,self).foo()
W.foo(self)
print "X"
class Y(W):
def foo(self):
print "Y"
class Z(X,Y):
def __init__(self):
self.foo()
Z.__mro__
z = Z()
If you look at class X, we can either use super to invoke the base class for X, or we can use a direct call to the base class W. The difference is, when super is used, python doesn't look for a specific implementation, but rather the first implementation in the current mro list. The mro list for Z is:
(Z,X,Y,W)
therefore, the one using super will print:
Y
X
while the one which directly calls the base will print:
W
X
Basically, using super dynamically invokes the first found implementation in the mro, while a class.foo (or in your case a self.foo) invokes that particular method.
The difference is that descendants of B
can properly participate in polymorphism since their foo()
method will be called if overridden, whereas C
does not have this option.
Suppose B
itself defines a foo
method, then self.foo()
would call B
's version of foo
. With C
's implementation, the super
call makes sure A
's version of foo
is called instead, even if C
also defines foo
.
精彩评论