31

decir que tengo los siguientes mixins que se solapa entre sí por tocar dispatch():¿Cómo afecta el orden de mixins a la clase derivada?

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) 

Si quiero mi punto de vista que pasar por el orden, compruebe A -> comprobar B, debe ser mi código MyView(FooMixin, BarMixin, View) o MyView(BarMixin, FooMixin, View) ?

¿Y por qué siempre ponemos View o sus subclases después de mixins? (He notado esto al leer el código fuente de las vistas genéricas de django, pero no sé cuál es el motivo, si lo hay)

Respuesta

57

El MRO es básicamente de profundidad, de izquierda a derecha. Consulte Method Resolution Order (MRO) in new style Python classes para obtener más información.

Puede consultar el __mro__ attribute de la clase para verificar, pero FooMixin debe ser el primero si primero desea hacer una "comprobación 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() 

Lienzo:

perform check A 
perform check B 
base dispatch 

View tiene que ser la última forma que se "atrapa" cualquier búsqueda de atributos que no estaban en ningún mixins, sin ocultar ningún método en esos mixins. No estoy seguro de entender esa parte de su pregunta: ¿qué es "por qué se agrega en absoluto" o "por qué se agrega al final"?

+1

thx agf. Mi pregunta estaba destinada a ser "por qué se agrega a la última" y usted la ha respondido. Aclamaciones. – tamakisquare

+1

Para que quede claro, el único método que esto llama directamente es 'FooMixin.dispatch'. 'super (FooMixin, self) .dispatch' luego evalúa como' BarMixin.dispatch' porque 'object' no tiene un método' dispatch'. 'super (BarMixin, self) .dispatch' se evalúa como' UltimateBase.dispatch' por el mismo motivo. –

+0

@MadPhysicist Eso no está del todo bien. Esto funcionará incluso si el método también está definido por un objeto: pruébelo usted mismo. Vea la respuesta vinculada para más información. – agf

Cuestiones relacionadas