【问题标题】:How does the order of mixins affect the derived class?mixin 的顺序如何影响派生类?
【发布时间】: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 通用视图的源代码时注意到了这一点,但我不知道它背后的原理,如果有的话)

【问题讨论】:

    标签: python django django-views django-class-based-views method-resolution-order


    【解决方案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 的调度将被最后调用。我的陈述本来应该是一个问题,但我分心了,忘了说清楚。谢谢你的回答:)
    猜你喜欢
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 2015-10-10
    • 2011-12-07
    • 1970-01-01
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多