Say, I have the following mixins that overlaps with each other by touching dispatch():
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)
If I want my view to go through the order, check A -> check B, should my code be MyView(FooMixin, BarMixin, View) or MyView(BarMixin, FooMixin, View)?
And why do we always put View or its subclasses after mixins? (I have noticed this from reading the source code of the django generic views, but I don't know the rationale behind it, if any)
Mixins are a language concept that allows a programmer to inject some code into a class. Mixin programming is a style of software development, in which units of functionality are created in a class and then mixed in with other classes. A mixin class acts as the parent class, containing the desired functionality.
It's perfectly valid for a mixin to inherit from another mixin - in fact, this is how most of Django's more advanced mixins are made. However, the idea of mixins is that they are reusable parts that, together with other classes, build a complete, usable class.
Mixins are sometimes described as being "included" rather than "inherited". In short, the key difference from an inheritance is that mix-ins does NOT need to have a "is-a" relationship like in inheritance. From the implementation point of view, you can think it as an interface with implementations.
Mixins are an alternative class design pattern that avoids both single-inheritance class fragmentation and multiple-inheritance diamond dependencies. A mixin is a class that defines and implements a single, well-defined feature. Subclasses that inherit from the mixin inherit this feature—and nothing else.
The MRO is basically depth-first, left-to-right. See Method Resolution Order (MRO) in new style Python classes for some more info.
You can look at the __mro__ attribute of the class to check, but FooMixin should be first if you want to do "check A" first.
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() Prints:
perform check A perform check B base dispatch View has to be last so that it "catches" any attribute lookups that weren't on any mixins, without hiding any methods on those mixins. I'm not sure I understand that part of your question -- what it "why is it added at all" or "why is it added last"?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With