31

說,我有以下的混入,通過觸摸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)

爲什麼我們總是在mixin之後放置View或它的子類? (我從django通用視圖的源代碼中已經注意到了這一點,但是我不知道它背後的基本原理,如果有的話)

回答

57

MRO基本上是從深度開始,從左到右。有關更多信息,請參閱Method Resolution Order (MRO) in new style Python classes

您可以查看該類的__mro__ attribute進行檢查,但如果您想先執行「檢查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必須在過去如此,它「抓獲」這不是在任何混入,不隱藏在那些混入任何方法的任何屬性查找。我不確定我是否理解了你的問題的部分內容 - 「它爲什麼添加」或「爲什麼最後添加」?

+1

thx agf。我的問題是爲了「爲什麼添加到最後」並且你已經回答了它。乾杯。 – tamakisquare 2012-04-05 18:05:18

+1

爲了清楚起見,這個直接調用的唯一方法是'FooMixin.dispatch'。 'super(FooMixin,self).dispatch'然後評估爲'BarMixin.dispatch',因爲'object'沒有'dispatch'方法。 'super(BarMixin,self).dispatch'由於同樣的原因評估爲'UltimateBase.dispatch'。 – 2018-01-31 21:48:43

+0

@MadPhysicist這不太對。即使該方法也是由對象定義的方法,這將起作用 - 請親自嘗試。有關更多信息,請參閱鏈接的答案。 – agf 2018-02-01 02:10:14

相關問題