2015-09-22 16 views
5

Powiedzmy, że mam 3 klasy: A, B i C. A jest klasą podstawową dla B, a B dla C. Hierarchia jest tu normalnie przechowywana, ale dla jednej metody powinna być inna. Dla klasy C powinien zachowywać się jak to zostało odziedziczone A.Python Dziedziczy z jednej klasy, ale zastępuje metodę wywołującą inną klasę?

Na przykład tak:

class A(object): 
    def m(self): 
     print 'a' 

class B(A): 
    def m(self): 
     super(B, self).m() 
     print 'b' 

class C(B): 
    def m(self): 
     super(A, self).m() 
     print 'c' 

Więc w zasadzie to powinno działać tak:

a = A() 
a.m() 
a 

b = B() 
b.m() 
a 
b 

c = C() 
c.m() 
a 
c 

Ale to nie będzie pracuję dla klasy C, ponieważ dostaję ten błąd:

AttributeError: 'super' object has no attribute 'm' 

Aby rozwiązać ten problem dla klasy C mogłem dziedziczyć z klas s A, ale chcę odziedziczyć wszystko z B i dla tej konkretnej metody m call super dla klasy bazowej A. Mam na myśli, że ta metoda jest jednym wyjątkiem. A może powinienem to jakoś inaczej nazwać dla klasy C, żeby zadziałała?

Jak mogę to zrobić?

+1

czy wypróbowałeś 'A.m (własny)' zamiast używać 'super'? –

+0

@MathiasEttinger nie, nie, ale teraz próbowałem i działa idealnie. Dzięki. Możesz umieścić go jako odpowiedź, ponieważ rozwiązał mój problem – Andrius

+0

, aby to zadziałało, A.m() musi być metodą klasy – fixmycode

Odpowiedz

4

Korzystając z połączenia, pyton sprawdzi, czy klasa klasy MRO będzie używana podczas wywoływania żądanej funkcji.

Ponieważ chcesz zwarcia ten problem, można jednoznacznie stwierdzić, klasę, której chcesz użyć metody od z:

class C(B): 
    def m(self): 
     A.m(self) 
     print 'c' 
8

Są to w rzeczywistości dwa sposoby, aby rozwiązać ten problem: można skrótów zadzwoń do super() i całkowicie ominąć MRO, jak w odpowiedzi Mathias Ettinger, albo może po prostu wydać poprawne wywołanie super():

class C(B): 
    def m(self): 
     super(B, self).m() 
     print 'c' 

Pamiętaj, że super() spodziewa się, jako pierwszy argument, klasę, z której powinien zacząć szukać mro. Zazwyczaj jest to klasa, w której wykonywane jest połączenie, ale jeśli chcesz, możesz przekazać inny poziom klasy w mro.

Powiązane problemy