はい、メソッド解決順序 ( C3 線形化)を計算するための新しいアルゴリズムを導入したドキュメントで説明されているように保証されています。
このアルゴリズムを使用しない実装は、mro
実際には Python 言語 (バージョン 2.3+) に準拠していません。私の知る限り、現在の実装はすべてC3線形化を使用しています。
C3 線形化は、局所的な優先順位と単調性のプロパティを満たします。ローカル優先順位とは、クラスが継承リストにリストされた順序で基本クラスC(B1, ..., Bn)
を持つことを意味します。mro
Bi
単調性は、おそらく次の例でよりよく説明されます。
>>> class A(object): pass
>>> class B(object): pass
>>> class C(object): pass
>>> class D(object): pass
>>> class E(object): pass
>>> class K1(A,B,C): pass
>>> class K2(D,B,E): pass
>>> class K3(D,A): pass
>>> class Z(K1,K2,K3): pass
python2.2 の古い mro (これは単調ではありません)。これらは上記のクラスの線形化です。
L[A] = A O
L[B] = B O
L[C] = C O
L[D] = D O
L[E] = E O
L[K1]= K1 A B C O
L[K2]= K2 D B E O
L[K3]= K3 D A O
L[Z] = Z K1 K3 A K2 D B C E O
# in current versions of python (2.3+):
# L[Z] = Z K1 K2 K3 D A B C E O
ここで、 の線形化ではクラスが の前に来るのZ
に対し、クラスの線形化では の後に来ることがわかります。単調性は線形化の特性であり、継承時にこの種のスワップはありません。クラスがクラスの親のすべての線形化でクラスに先行する場合、最終的な線形化でもクラスに先行します。A
D
K3
D
X
Y
Y
さて、クラスを考えてみC(B1, ..., Bn)
ます。ローカル優先順位により、クラスB1, ..., Bn
は の線形化でその順序で検出されC
ます。Bi
単調性により、s 自体の前に s のサブクラスを見つけることはできませんBi
。このことから、 の線形化が存在する場合、とC
で開始する必要があることがわかります。C
B1
場合によっては、線形化を計算できないことに注意してください。Python は次のように文句を言います。
>>> class A(object):pass
...
>>> class B(object, A): pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Cannot create a consistent method resolution
order (MRO) for bases object, A
ただし、クラスを交換すると、階層を線形化することができます。
>>> class B(A, object): pass
...
>>> B.mro()
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
親クラスに共通のベースがない場合 (object
明らかにそれ以外)、 の線形化が( を除く)C(B1, ..., Bn)
の線形化で始まり、etcの線形化が続き、 の線形化で終わることは明らかです。B1
object
B2
Bn
>>> class A(object): pass
...
>>> class B(object): pass
...
>>> class A1(A): pass
...
>>> class A2(A1): pass
...
>>> class B1(B): pass
...
>>> class C(object): pass
...
>>> class C1(C): pass
...
>>> class C2(C1):pass
...
>>> class C3(C2): pass
...
>>> class D(A2, B1, C3): pass
...
>>> D.mro()
[<class '__main__.D'>, <class '__main__.A2'>, <class '__main__.A1'>, <class '__main__.A'>, <class '__main__.B1'>, <class '__main__.B'>, <class '__main__.C3'>, <class '__main__.C2'>, <class '__main__.C1'>, <class '__main__.C'>, <class 'object'>]
s の間にいくつかの共通のサブクラスがあると、事態は奇妙になり始めますBi
。この場合、python は、ローカルの優先順位と単調性に違反しないと予想される順序を見つけるか、エラーが発生します。