多重継承オブジェクト指向言語でのメソッド解決のためのC3線形化アルゴリズム:実装の詳細の正当化の探求


7

この Pythonのメソッド解決順序(mro)、別名C3線形化の説明によれば、アルゴリズムは次のように再帰的に説明できます。

L(O) = <O>
L(C) = <C> + merge(L(B1),..., L(Bn), <B1,...,Bn>)

どこ

  • O すべてのクラスが継承するクラスです。
  • Cは、、B1...、から直接Bnこの順序で継承するクラスです。
  • <および>リスト区切り文字です。
  • + リスト連結演算子です。
  • merge 以下で説明する方法で、そのリスト引数を単一のリストにマージします。

上記は単語で言い換えることができます(上記のPythonドキュメントから引用):

Cの線形化は、Cと、親の線形化と親のリストのマージの合計です。

merge(本質的にPythonのドキュメントから引用したが、わずかに言い換え)以下のようなアルゴリズムが記載されています。

最初のリストの先頭、つまりL(B1)[0]を検討します。それが良い先頭である場合、つまり他のリストの適切な末尾にない場合は、Cの線形化に追加して削除しますマージのすべてのリストから。そうでない場合は、次のリストの頭などを検討します。クラスがなくなるか、頭がなくなるまで繰り返します。後者の場合、マージを構築することは不可能です。

次の例は、説明のためのものです。仮定Aから直接継承するBC、このために、との線形化したとするBCしています

L(B) = <B, D, E, O>
L(C) = <C, D, F, O>

次に、A線形化は

L(A) = <A> + merge(<B,D,E,O>, <C,D,F,O>, <B,C>)
     = <A, B> + merge(<D,E,O>, <C,D,F,O>, <C>)
     = <A, B, C> + merge(<D,E,O>, <D,F,O>)
     = <A, B, C, D> + merge(<E,O>, <F,O>)
     = <A, B, C, D, E> + merge(<O>, <F,O>)
     = <A, B, C, D, E, F> + merge(<O>, <O>)
     = <A, B, C, D, E, F, O>

私の質問は、アルゴリズムの元の説明に関して、<B1,...,Bn>直接の親のリストを引数として提供する目的は何mergeですか?この引数を省略した場合、アルゴリズムは異なる結果を生成しますか?

回答:


5

最後のリストなし:

merge(<B,D,O>, <C,F,O>, <D,O>) =
  <B,D,C,F,O> 

最後のリストで:

merge(<B,D,O>, <C,F,O>, <D,O>, <B,C,D>) =
  <B> + merge(<D,O>, <C,F,O>, <D,O>, <C,D>) =
  <B,C> + merge(<D,O>, <F,O>, <D,O>, <D>) =
  <B,C,D,F,O>

最後のリストなし:

merge(<B,D,C,O>, <C,F,O>, <D,O>) =
  <B,D,C,F,O> 

最後のリストで:

merge(<B,D,C,O>, <C,F,O>, <D,O>, <B,C,D>) =
  <B> + merge(<D,C,O>, <C,F,O>, <D,O>, <C,D>) =
  no-merge

直感的に、最後のリストは、最終結果が順序と互換性を持つように強制します<B1,...,Bn>。これにより、順序が変更されたり、マージが失敗したりする可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.