Как порядок миксинов влияет на производный класс?
Скажем, у меня есть следующие микшины, которые перекрываются друг с другом, прикоснувшись к 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)
Если я хочу, чтобы мое представление проходило через заказ, проверьте A → проверку B, должен ли мой код MyView(FooMixin, BarMixin, View)
или MyView(BarMixin, FooMixin, View)
?
И почему мы всегда ставим View
или его подклассы после mixins? (Я заметил это от чтения исходного кода общих представлений django, но я не знаю его обоснования, если есть)
Ответы
Ответ 1
MRO в основном имеет глубину - сначала, слева направо. См. Порядок разрешения метода (MRO) в классах Python нового стиля для получения дополнительной информации.
Вы можете посмотреть атрибут __mro__
класса для проверки, но FooMixin
должен быть первым, если вы хотите сделать "сначала проверьте 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()
Печать
perform check A
perform check B
base dispatch
View
должен быть последним, чтобы он "ловил" любые поиски атрибутов, которые не были на каких-либо смесях, не скрывая никаких методов для этих микшинов. Я не уверен, что понимаю эту часть вашего вопроса - что она "почему она вообще добавлена" или "почему она добавлена последним"?
Ответ 2
Это то же самое, что и вы:
class UltimateBase(object):
def dispatch(self, *args, **kwargs):
print 'base dispatch'
class FooMixin(UltimateBase):
def dispatch(self, *args, **kwargs):
print 'perform check A'
return super(FooMixin, self).dispatch(*args, **kwargs)
class BarMixin(FooMixin):
def dispatch(self, *args, **kwargs):
print 'perform check B'
return super(BarMixin, self).dispatch(*args, **kwargs)
class FooBar(BarMixin):
pass
FooBar().dispatch()