31

Dire, ho il seguente mixins che si sovrappone con l'altro toccando dispatch():In che modo l'ordine dei mixin influisce sulla classe derivata?

class FooMixin(object): 
    def dispatch(self, *args, **kwargs): 
     # perform check A 
     ... 
     return super(FooMixin, self).dispatch(*args, **kwargs) 

class BarMixin(object): 
    def dispatch(self, *args, **kwargs): 
     # perform check B 
     ... 
     return super(FooMixin, self).dispatch(*args, **kwargs) 

Se voglio mio punto di vista di passare attraverso l'ordine, controllare A -> controllare B, dovrebbe il mio codice essere MyView(FooMixin, BarMixin, View) o MyView(BarMixin, FooMixin, View) ?

E perché mettiamo sempre View o le sue sottoclassi dopo i mix? (Ho notato questo dalla lettura del codice sorgente delle viste generiche di django, ma non conosco la logica alla base, se presente)

risposta

57

L'MRO è fondamentalmente in profondità, da sinistra a destra. Vedi Method Resolution Order (MRO) in new style Python classes per ulteriori informazioni.

È possibile controllare lo __mro__ attribute della classe da controllare, ma il FooMixin dovrebbe essere il primo se si desidera eseguire prima "controllo A".

class UltimateBase(object): 
    def dispatch(self, *args, **kwargs): 
     print 'base dispatch' 

class FooMixin(object): 
    def dispatch(self, *args, **kwargs): 
     print 'perform check A' 
     return super(FooMixin, self).dispatch(*args, **kwargs) 

class BarMixin(object): 
    def dispatch(self, *args, **kwargs): 
     print 'perform check B' 
     return super(BarMixin, self).dispatch(*args, **kwargs) 

class FooBar(FooMixin, BarMixin, UltimateBase): 
    pass 

FooBar().dispatch() 

stampe:

perform check A 
perform check B 
base dispatch 

View deve essere ultimo in modo che si "cattura" qualsiasi attributo ricerche che non erano in alcun mixins, senza nascondere eventuali metodi su tali mixins. Non sono sicuro di aver capito quella parte della tua domanda - che cosa "perché viene aggiunta del tutto" o "perché è stata aggiunta per ultima"?

+1

thx agf. La mia domanda è stata pensata per essere "perché è aggiunta all'ultimo" e tu hai risposto. Saluti. – tamakisquare

+1

Giusto per essere chiari, l'unico metodo che chiama direttamente "FooMixin.dispatch". 'super (FooMixin, self) .dispatch' quindi valuta' BarMixin.dispatch' perché 'object' non ha un metodo' dispatch'. 'super (BarMixin, self) .dispatch' restituisce' UltimateBase.dispatch' per lo stesso motivo. –

+0

@MadPhysicist Non è giusto. Funzionerà anche se il metodo è definito anche da oggetto: provalo tu stesso. Vedi la risposta collegata per maggiori informazioni. – agf