super
действительно предназначен для этой ситуации, но он работает только в том случае, если вы используете его последовательно. Если базовые классы не все также используют super
, это не сработает, и если метод не находится в object
, вы должны использовать что-то вроде общего базового класса для завершения цепочки вызовов super
.
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 спрашивает, почему там должно быть общее основание:
Без FooBase
, который реализует foo
но не называют super()
последний класс, который действительно требует super()
получите ошибку атрибута как нет базовый метод для вызова.
Если были отдельные базовые классы class A(AFooBase):
и class B(BFooBase):
super()
вызов в A
бы вызвать метод в AFooBase
и метод в B
никогда не будет вызван. Когда база является общей для всех классов, она подходит к концу порядка разрешения метода, и вы можете быть уверены, что независимо от того, как будут определены классы, метод базового класса будет последним.
Спасибо за ответ. Теперь я больше не чувствую себя грязным, потому что не использовал super(). – sayap
При явном вызове методов базового класса * может * работать для очень простых сценариев, таких как пример опроса, он сломается, если базовые классы сами наследуют от общей базы, и вы не хотите, чтобы метод конечного базового класса вызывался дважды , Это известно как «наследование бриллиантов», и это большая проблема для многих множественных систем наследования (например, на C++). Совместное многократное наследование Python (с помощью 'super()') позволяет легко решить его во многих случаях (хотя это не означает, что совместная иерархия множественного наследования проста в дизайне или всегда хорошая идея). – Blckknght