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.dispatch
。 super(FooMixin, self).dispatch
然后计算为 BarMixin.dispatch
,因为 object
没有 dispatch
方法。出于同样的原因,super(BarMixin, self).dispatch
的计算结果为 UltimateBase.dispatch
。
@MadPhysicist 这不太对。即使该方法也是由对象定义的方法,这也将起作用-您自己尝试一下。有关更多信息,请参阅链接的答案。
@agf。当然。我的错。 object
的调度将被最后调用。我的陈述本来应该是一个问题,但我分心了,忘了说清楚。谢谢你的回答:)以上是关于mixin 的顺序如何影响派生类?的主要内容,如果未能解决你的问题,请参考以下文章