super
is indeed intended for this situation, but it only works if you use it consistently. If the base classes don't also all use super
it won't work, and unless the method is in object
you have to use something like a common base class to terminate the chain of super
calls.
class FooBase(object):
def foo(self): pass
class A(FooBase):
def foo(self):
super(A, self).foo()
print 'A.foo()'
class B(FooBase):
def foo(self):
super(B, self).foo()
print 'B.foo()'
class C(A, B):
def foo(self):
super(C, self).foo()
print 'C.foo()'
@Marcin asks why there has to be a common base:
Without FooBase
that implements foo
but doesn't call super()
the last class that does call super()
will get an attribute error as there is no base method to call.
If there were separate base classes class A(AFooBase):
and class B(BFooBase):
the super()
call in A
would call the method in AFooBase
and the method in B
would never be called. When the base is common to all of the classes it goes to the end of the method resolution order and you can be certain that no matter how the classes are defined the base class method will be the last one called.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…