31

말, 나는 dispatch()을 터치하여 서로 겹치는 다음이나 mixin 있습니다mixins의 순서는 어떻게 파생 클래스에 영향을 줍니까?

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 또는 그 하위 클래스를 mixins 뒤에 넣을까요? (장고 일반 뷰의 소스 코드를 읽은 것으로 알았지 만 그이면의 이유를 모르는 경우)

답변

57

MRO는 기본적으로 깊이 우선, 왼쪽에서 오른쪽입니다. 자세한 내용은 Method Resolution Order (MRO) in new style Python classes을 참조하십시오.

클래스의 __mro__ attribute에서 확인할 수 있지만 먼저 "확인"을하려면 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 마지막이어야한다 있도록 "잡는다"그 유지 mixin에 어떤 방법을 숨기지 않고, 어떤 유지 mixin에되지 않은 모든 속성 조회. 질문의 일부를 이해하고 있는지, "왜 그것이 전혀 추가되지 않았을까", "왜 마지막으로 추가되는 것입니까?"

+1

thx agf. 내 질문은 "마지막에 추가 된 이유는 무엇인가?"라는 질문이었고 대답했습니다. 건배. – tamakisquare

+1

이 호출을 직접 호출하는 유일한 방법은'FooMixin.dispatch'입니다. 'super (FooMixin, self) .dispatch'는'object'에'dispatch' 메소드가 없기 때문에'BarMixin.dispatch'로 평가됩니다. 'super (BarMixin, self) .dispatch'는 같은 이유로 "UltimateBase.dispatch"로 평가됩니다. –

+0

@MadPhysicist 그건 옳지 않아. 메서드가 객체로 정의 된 경우에도 작동합니다. 직접 시도하십시오. 자세한 내용은 링크 된 답변을 참조하십시오. – agf

관련 문제