super
jest rzeczywiście przeznaczony do tej sytuacji, ale działa tylko wtedy, gdy używasz go konsekwentnie. Jeśli klasy bazowe nie wszystkie również używają super
, to nie zadziała i chyba że metoda jest w object
musisz użyć czegoś podobnego do zwykłej klasy bazowej, aby zakończyć połączenia 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 pyta, dlaczego nie musi być wspólna podstawa:
Bez FooBase
który implementuje foo
ale nie wywołuje super()
ostatnia klasa, która ma wywołać super()
dostanie błąd atrybutu jak tam nie ma podstawowa metoda wywoływania.
Gdyby nie było odrębnych klas bazowych class A(AFooBase):
i class B(BFooBase):
wywołanie w A
super()
nazwałbym Sposób AFooBase
i metody w B
nigdy nie zostanie wywołana. Gdy podstawa jest wspólna dla wszystkich klas, przechodzi do końca kolejności rozwiązywania metod i możesz mieć pewność, że niezależnie od tego, jak zdefiniowane zostaną klasy, metoda klasy bazowej będzie ostatnią wywołaną.
Dzięki za odpowiedź. Teraz nie czuję się już brudny, ponieważ nie używam super(). – sayap
Podczas gdy jawne wywoływanie metod klasy podstawowej * może * działać dla bardzo prostych scenariuszy, takich jak przykład osoby pytającej, ulegnie ona rozbiciu, jeśli klasy podstawowe same odziedziczą ze wspólnej podstawy i nie chcesz, aby metoda najwyższej klasy bazy była wywoływana dwa razy . Jest to znane jako "dziedziczenie diamentów" i jest to duży problem dla wielu systemów dziedziczenia (jak w C++). Wspólne dziedziczenie Pythona (z 'super()') pozwala w wielu przypadkach łatwo go rozwiązać (choć nie oznacza to, że hierarchia dziedziczenia wielu spółdzielni jest łatwa do zaprojektowania lub zawsze jest dobrym pomysłem). – Blckknght