Подтвердить что ты не робот

Как порядок миксинов влияет на производный класс?

Скажем, у меня есть следующие микшины, которые перекрываются друг с другом, прикоснувшись к 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, но я не знаю его обоснования, если есть)

4b9b3361

Ответ 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()