2013-06-11 6 views
9

はあなたが混在階層を持っているとき、どのようにPythonの振る舞いの相対は解決順序を継承と方法するん 古いスタイルクラスと新しいスタイルクラスを階層に混在させるとどうなりますか?

class A(B1,B2): pass 
class B1(C1, C2): pass 
class B2: pass 
class C1(object): pass 
class C2: pass 

のようなものを持っていると仮定しますか?古いトラバーサル、新しいトラバーサル、階層のどの枝が歩いているかに応じて2つの組み合わせに従っていますか? docsから

+1

woah ...明らかに質問のような人々。ありがとうございます –

答えて

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を計算するために使用される唯一のものである。

+0

'inspect.getmro()'は、古いスタイルの階層でも発生する可能性がありますが、同じ基本クラスを2回返すことはありません。これは単に 'inspect.getmro()'を使うことの副作用です。この場合の実際のMROは、同じ基本クラスで何度か検索します。 –

1

Cの線形化は、Cの合計を加えた両親の 線形化のマージや両親のリストです。

これは、階層のどの枝で現在歩いているか(つまり混在しているかどうか)によって決まります。

これは再帰的に行われなければならないので、私は別の動作を期待しません。

関連する問題