mro はメソッド解決順序 (メソッド解釈順序) であり、主に多重継承時に属性のパス (どのクラスから来たのか) を決定するために使用されます。
python2.2バージョンでは、アルゴリズムの基本的な考え方は、検索されたクラスを含む各祖先クラスの継承構造に基づいてリストを作成し、戦略に従って重複を削除することです。しかし、単調性(逐次保存)を維持できないため、バージョン2.3からは新しいアルゴリズムC3が採用されました。
C3 アルゴリズムを使用する理由
C3 アルゴリズムは最初に Lisp 用に提案されました。元の深さ優先検索アルゴリズムがローカル優先度と単調性を満たさないという問題を解決するために Python に適用されました。
ローカル優先度: C(A,B) など、宣言時の親クラスの順序を指します。クラス C オブジェクトのプロパティにアクセスする場合は、最初にクラス A を検索し、次にクラスを検索する必要があります。宣言の順序に従ってB。
単調性: C の解析順序で A が B より前にランクされている場合、この順序は C のすべてのサブクラスでも満たされる必要があります。
C3 アルゴリズム
mro を決定するには、まず線形シーケンスを決定する必要があります。次に、シーケンス内のクラスの順序によって検索パスが決定されます。したがって、C3 アルゴリズムは線形シーケンスを生成します。
基本クラスから継承する場合:
このとき、B の mro シーケンスは [B,A]
複数の基本クラスから継承する場合
シーケンスの最初の要素が他のシーケンスの最初の要素である場合、または他のシーケンスに表示されない場合は、マージ操作を実行するすべてのシーケンスからこの要素を削除し、マージします。ミスターの現在のもの。
マージ操作後のシーケンスは、マージ操作のシーケンスが空になるまでマージ操作を実行し続けます。
マージ操作のシーケンスを空にできない場合、それは不正であることを意味します。
例:
A、B、および C はすべて基本クラスから継承するため、mro シーケンスは [A,O]、[B,O]、[C,O] となります
A はシーケンス [A, O] の最初の要素ですが、シーケンス [B, O] には現れず、シーケンス [A, B] の最初の要素でもあるため、マージ操作が実行されます。([A,O]、[B,O]、[A,B]) から A を削除し、現在の mro、[E] にマージします。
mro(E) = [E,A] + merge([O], [B,O], [B])
マージ操作を再度実行します。O はシーケンス [O] の最初の要素ですが、O はシーケンス [B, O] にあり、最初の要素ではありません。引き続き、[B, O] の最初の要素 B に注目します。B は条件を満たすため、マージ操作が実行されるシーケンスから B が削除され、[E, A] にマージされます。
C3 アルゴリズムを実装するコード