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)
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"?
来源:https://stackoverflow.com/questions/10018757/how-does-the-order-of-mixins-affect-the-derived-class