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

Posted

技术标签:

【中文标题】mixin 的顺序如何影响派生类?【英文标题】:How does the order of mixins affect the derived class? 【发布时间】:2012-04-18 14:41:09 【问题描述】:

说,我有以下通过触摸dispatch()相互重叠的mixin:

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 或其子类放在mixin 之后? (我在阅读 django 通用视图的源代码时注意到了这一点,但我不知道它背后的原理,如果有的话)

【问题讨论】:

【参考方案1】:

MRO 基本上是深度优先,从左到右。请参阅Method Resolution Order (MRO) in new style Python classes 了解更多信息。

你可以查看类的__mro__ attribute来检查,但是如果你想先做“检查A”,FooMixin应该是第一个。

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 必须放在最后,这样它才能“捕获”任何不在任何 mixins 上的属性查找,而不会隐藏这些 mixins 上的任何方法。我不确定我是否理解您问题的那一部分——“为什么要添加它”或“为什么最后添加它”?

【讨论】:

感谢 agf。我的问题是“为什么要添加到最后”,而您已经回答了。干杯。 明确一点,这个直接调用的唯一方法是FooMixin.dispatchsuper(FooMixin, self).dispatch 然后计算为 BarMixin.dispatch,因为 object 没有 dispatch 方法。出于同样的原因,super(BarMixin, self).dispatch 的计算结果为 UltimateBase.dispatch @MadPhysicist 这不太对。即使该方法也是由对象定义的方法,这也将起作用-您自己尝试一下。有关更多信息,请参阅链接的答案。 @agf。当然。我的错。 object 的调度将被最后调用。我的陈述本来应该是一个问题,但我分心了,忘了说清楚。谢谢你的回答:)

以上是关于mixin 的顺序如何影响派生类?的主要内容,如果未能解决你的问题,请参考以下文章

C++创建派生类对象时,调用构造函数顺序

派生类的构造函数与析构函数的调用顺序

阿里笔试题-派生类构造函数 创建顺序

派生类的构造函数学习之调用顺序

派生类(构造函数)中基类的成员变量初始化顺序

python入行030(mixins机制派生与方法重用)