web-dev-qa-db-ja.com

ミックスインの順序は派生クラスにどのように影響しますか?

言う、私はdispatch()に触れることによって互いにオーバーラップする次のミックスインを持っています:

_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またはそのサブクラスをミックスインの後に置くのですか? (Djangoジェネリックビューのソースコードを読んでこれに気づきましたが、その背後にある根拠があったとしてもわかりません)

49
tamakisquare

MROは基本的に深さ優先、左から右です。詳細については、 新しいスタイルのメソッド解決順序(MRO)Python classes を参照してください。

__mro__チェックするクラスの属性 ですが、「チェック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は、ミックスインのメソッドを非表示にすることなく、ミックスインにない属性ルックアップを「キャッチ」するために、最後でなければなりません。私はあなたの質問のその部分を理解しているのかわかりません-それが「なぜそれがまったく追加されたのですか」または「なぜ最後に追加されたのですか」?

73
agf