2011-06-09 14 views
6

Ho una classe:Mixin, multi-ereditarietà, costruttori e dati

class A(object): 
    def __init__(self, *args): 
     # impl 

Anche un "mixin", in pratica un'altra classe con alcuni dati e metodi:

class Mixin(object): 
    def __init__(self): 
     self.data = [] 

    def a_method(self): 
     # do something 

Ora creo una sottoclasse di a con la mixin:

class AWithMixin(A, Mixin): 
    pass 

mio problema è che voglio che i costruttori di a e mixin entrambi chiamati. Ho preso in considerazione l'idea di assegnare ad AWithMixin un costruttore proprio, in cui è stato chiamato il super, ma i costruttori delle super classi hanno liste di argomenti differenti. Qual è la migliore risoluzione?

+1

Cosa ti impedisce di chiamare i costruttori delle due classi base (con la loro ar appropriata gumenti) da "AWithMixin .__ init__'? – NPE

+0

A questo è già stata data una risposta approfondita. Vedi http://stackoverflow.com/a/6100595/763269 –

risposta

8

Sono abbastanza nuovo per OOP troppo, ma quello che è il problema su questo codice:

class AWithMixin(A, Mixin): 
    def __init__(self, *args): 
     A.__init__(self, *args) 
     Mixin.__init__(self) 
+2

questa è la soluzione migliore e la uso sempre. Tuttavia, se sia 'A' che' Mixin' estendono alcune classi (es. 'Base') ed entrambi chiamano' Base .__ init __() 'può essere obbligatorio usare la funzione [super()] (http: // stackoverflow. com/q/576.169). È complicato IMHO e raccomando di saperlo ma evitarlo se possibile. – brandizzi

+0

@brandizzi, come ho detto sulla risposta, sono nuovo di OOP. Ho guardato la super funzione, ma non ho capito. Se ho detto su questa classe [codice] super (AWithMixin, self) .__ init __() [/ code], come posso chiamare A .__ init__ e Mixin .__ init__ entrambi? E specificare diversi argomenti? – utdemir

+1

Il problema è che questa soluzione non è particolarmente estensibile e ignora completamente il punto di incapsulamento e specifica il mixin nell'ordine sbagliato. Se vuoi sovrascrivere i metodi in un mixin, allora quel mixin prende il controllo su quel metodo e dovrebbe essere responsabile di chiamare lo stesso metodo in una super classe. Il fatto che il mixin richieda una lista di argomenti diversa suggerisce che è codificato in modo errato/non è stato progettato per l'uso con questa classe di bambini - è in violazione di [LSP] (http://en.wikipedia.org/wiki/Liskov_substitution_principle)) . – quodlibetor

10
class A_1(object): 
    def __init__(self, *args, **kwargs): 
     print 'A_1 constructor' 
     super(A_1, self).__init__(*args, **kwargs) 

class A_2(object): 
    def __init__(self, *args, **kwargs): 
     print 'A_2 constructor' 
     super(A_2, self).__init__(*args, **kwargs) 

class B(A_1, A_2): 
    def __init__(self, *args, **kwargs): 
     super(B, self).__init__(*args, **kwargs) 
     print 'B constructor' 

def main(): 
    b = B() 
    return 0 

if __name__ == '__main__': 
    main() 
  1. A_1 costruttore
  2. A_2 costruttore
  3. B costruttore