次のようなものがあるとします
class C2: pass
class C1(object): pass
class B2: pass
class B1(C1, C2): pass
class A(B1,B2): pass
階層が混在している場合、Python は継承とメソッド解決の順序に対してどのように動作しますか? 古いトラバーサル、新しいトラバーサル、階層のどのブランチが歩いているかに応じて 2 つの組み合わせに従うか?
次のようなものがあるとします
class C2: pass
class C1(object): pass
class B2: pass
class B1(C1, C2): pass
class A(B1,B2): pass
階層が混在している場合、Python は継承とメソッド解決の順序に対してどのように動作しますか? 古いトラバーサル、新しいトラバーサル、階層のどのブランチが歩いているかに応じて 2 つの組み合わせに従うか?
答えは「2つの組み合わせ」です。inspect.getmro()
古いスタイルのクラスと新しいスタイルのクラスの両方で機能する を使用して、自分で確認できます。MRO、つまりメソッド解決順序を返します。
古いスタイルのクラスには、深さ優先、最初から最後までのベースである MRO があります。(これは、最も複雑なケースでは悪い考えですが、下位互換性を維持するために残されています。) すべての親クラスの MRO が既に計算されているため、次のように表現できます。
mro(new_class) = [new_class] + mro(first_base) + mro(second_base) + ...
新しいスタイルのクラスの場合、アルゴリズムは同じ基本的な考え方を使用しますが、より複雑です --- これも で始まりますが、その後にリスト、など[new_class]
のより巧妙なマージが続きます。mro(first_base)
mro(second_base)
これらの基底クラスのそれぞれが古いスタイルか新しいスタイルかに関係なく、以前に計算された独自の MRO が既にあり、これらの MRO (リストとして) は、新しいクラスの MRO を計算するために使用される唯一のものです。