31

Demek, dispatch() dokunarak birbirleriyle örtüşür aşağıdaki katmalar vardır:Karışımların sırası türetilmiş sınıfı nasıl etkiler?

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) 

ben sırayla geçmesi görüşümü istiyorsanız, kontrol A -> B kontrol benim kodu olmalıdır MyView(FooMixin, BarMixin, View) veya MyView(BarMixin, FooMixin, View) ?

Ve neden hep View veya Mixins sonra alt sınıfları koyacağım? (Bunun django genel görünümlerinin kaynak kodunu okumasını fark ettim, ancak arkasındaki mantığı bilmiyorum, varsa)

cevap

57

MRO temelde derinlik-ilk, soldan sağa doğrudur. Daha fazla bilgi için Method Resolution Order (MRO) in new style Python classes adresine bakın.

Sınıfın __mro__ attribute numarasını incelemek için bakabilirsiniz, ancak önce "A kontrol et" yapmak istiyorsanız FooMixin ilk önce olmalıdır.

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() 

Baskılar:

perform check A 
perform check B 
base dispatch 

View son olması gerektiğini bu nedenle "av" bu Mixins üzerinde herhangi yöntemleri saklamadan, herhangi Mixins değildi herhangi özellik aramaları. Sorunuzun o kısmını anladığımdan emin değilim - niçin "neden ekleniyor" veya "neden son ekleniyor"?

+1

thx agf. Sorumum "neden son ekledi" olmalıydı ve sen cevapladın. Şerefe. – tamakisquare

+1

Daha açıkçası, bu çağrıları tek yöntem, doğrudan 'FooMixin.dispatch' olduğunu. 'Nesnesi' bir' dispatch' yöntemi yok 'çünkü süper (FooMixin, kendinden) .dispatch' sonra BarMixin.dispatch'' olarak değerlendirilir. 'Aynı nedenle UltimateBase.dispatch'' sonucunu .dispatch' süper (BarMixin, kendinden). –

+0

@MadPhysicist Bu doğru değil. Bu yöntem, nesne tarafından da tanımlanmış olsa bile çalışır - kendiniz deneyin. Daha fazla bilgi için bağlantılı cevaba bakınız. – agf