2015-09-22 14 views
5

Diciamo che ho 3 classi: A, B e C. A è una classe base per B e B è per C. La gerarchia viene mantenuta normalmente qui, ma per un metodo dovrebbe essere diverso. Per la classe C dovrebbe agire come se fosse stato ereditato da A.Python Inherit da una classe, ma il metodo override chiama un'altra classe?

Ad esempio come questo:

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' 

Quindi, in pratica dovrebbe funzionare in questo modo:

a = A() 
a.m() 
a 

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

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

Ma non è andare a lavoro per la classe C, perché ottengo questo errore:

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

Per risolvere questo per classe C ho potuto ereditare da clas s A, ma voglio ereditare tutto da B e per quel metodo specifico chiamata m super per la classe base A. Voglio dire che il metodo è un'eccezione. O dovrei chiamarlo in qualche modo in modo diverso per la classe C per funzionare?

Come posso farlo?

+1

hai provato 'A.m (self)' invece di usare 'super'? –

+0

@ MathiasEttinger no, non l'ho fatto, ma ora l'ho provato e funziona perfettamente. Grazie. Puoi postarlo come risposta, perché ha risolto il mio problema – Andrius

+0

affinché funzioni, A.m() deve essere un metodo di classe – fixmycode

risposta

4

Utilizzando la chiamata super, python ispezionerà lo MRO della classe per determinare quale classe utilizzare quando si chiama la funzione desiderata.

Dal momento che si desidera cortocircuitare questo comportamento, è possibile indicare esplicitamente la classe che si desidera utilizzare il metodo da con:

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

Ci sono infatti due modi per risolvere questo: è possibile scorciatoia chiami a super() e totalmente ignorare l'MRO come nella risposta di Mathias Ettinger, oppure si può semplicemente rilasciare il corretta chiamata a super():

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

Ricordate che super() prevede come primo argomento la classe da cui dovrebbe iniziare a cercare il mro. Di solito è la classe in cui viene effettuata la chiamata, ma è possibile passare un'altra tomaia di classe nel mro se si desidera.

Problemi correlati