Python では、クラスを定義するときに、その親クラスを指定できます。サブクラスは親クラスのすべてのプロパティとメソッドを継承し、独自の一意のプロパティとメソッドを追加できます。
ただし、クラスに複数の直接の親クラスがある場合、これらの親クラス間に同じ名前のプロパティやメソッドが存在する可能性があります。これらのプロパティとメソッドを正しく呼び出すために、Python は「メソッド解決順序」(メソッド解決順序、MRO) と呼ばれるアルゴリズムを使用して、プロパティとメソッドの検索順序を決定します。
Python 2.x では、MRO は深さ優先検索アルゴリズム (DFS) を使用して実装されます。このアルゴリズムにはいくつかの問題があり、場合によってはメソッド呼び出しシーケンスが正しく解析されません。例:
class A: def foo(self): print("A.foo") class B(A): pass class C(A): def foo(self): print("C.foo") class D(B, C): pass d = D() d.foo() # 输出"A.foo",而不是"C.foo"
上記のコードでは、クラス D はクラス B とクラス C を継承し、クラス C はクラス A の foo() メソッドをオーバーライドします。したがって、オブジェクト d の foo() メソッドを呼び出すときは、理論的にはクラス C の foo() メソッドを最初に呼び出す必要があります。ただし、Python 2.x は DFS アルゴリズムを使用するため、最初にクラス B、次にクラス C、最後にクラス A を走査します。したがって、クラス C の foo() メソッドではなく、クラス A の foo() メソッドが最終的に呼び出されます。
この問題を解決するために、Python 2.3 では C3 アルゴリズムが導入されました。このアルゴリズムは、トポロジカル ソート アルゴリズムを使用して MRO リストを計算し、メソッド呼び出し時の正確性を保証します。 C3 アルゴリズムの基本原理は次のとおりです。
新しいスタイルのクラス (つまり、明示的にオブジェクトを継承するクラス、または暗黙的にオブジェクトを継承するクラス) の MRO リストは、次に従って計算されます。幅優先検索 (BFS) アルゴリズム。
各クラスの MRO リストは次の 3 つの条件を満たす必要があります。
サブクラスの MRO リストは次のランクにある必要があります。親クラスの MRO リストの先頭。
2 つの親クラスが子クラスの MRO リストに表示される場合、リスト内でのそれらの相対的な順序は、子クラスの直接の親クラスでの出現と一致している必要があります。順番も同じです。
__mro__ 属性を通じてクラスの MRO リストを表示できます。例:
class A: def foo(self): print("A.foo") class B(A): pass class C(A): def foo(self): print("C.foo") class D(B, C): pass print(D.__mro__)
(そのうち、, , 、<クラス '__main__.A'>、<クラス 'オブジェクト'>)
<クラス ' __main__.D '> はクラス D 自体を表し、
および
は親を表します。クラス D のそれぞれクラス B とクラス C、
は、クラス B と C の共通の親クラス A を表します、
はすべての新しいスタイルのクラスの基本クラスを表します。このリストの順序は、Python の実行時にプロパティとメソッドが検索される順序です。
以上がPython サブクラスは多重継承で MRO をどのように使用しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。