mixin的顺序如何影响派生类?

tam*_*are 47 python django django-views method-resolution-order django-class-based-views

说,我有以下mixin通过触摸相互重叠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)
Run Code Online (Sandbox Code Playgroud)

如果我希望我的视图通过订单,请检查A - >检查B,如果我的代码是MyView(FooMixin, BarMixin, View)或者MyView(BarMixin, FooMixin, View)

为什么我们总是View在mixins之后放入或者它的子类?(我从阅读django通用视图的源代码中注意到了这一点,但我不知道它背后的基本原理,如果有的话)

agf*_*agf 78

MRO基本上是深度优先,从左到右.有关更多信息,请参阅新样式Python类中的方法解析顺序(MRO).

您可以查看要检查的类的__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()
Run Code Online (Sandbox Code Playgroud)

打印:

perform check A
perform check B
base dispatch
Run Code Online (Sandbox Code Playgroud)

View必须是最后的,以便它"捕获"任何不在任何mixin上的属性查找,而不隐藏任何mixin上的方法.我不确定我理解你问题的那一部分 - 它是什么"为什么它会被添加"或"为什么它会被添加到最后"?

  • 谢谢 agf。我的问题本来是“为什么它被添加到最后”,你已经回答了。干杯。 (2认同)
  • 需要说明的是,this 直接调用的唯一方法是`FooMixin.dispatch`。`super(FooMixin, self).dispatch` 然后评估为 `BarMixin.dispatch`,因为 `object` 没有 `dispatch` 方法。出于同样的原因,`super(BarMixin, self).dispatch` 评估为 `UltimateBase.dispatch`。 (2认同)