2

Python Web ページのドキュメントでは、python のクラシック クラスのメソッド解決順序は、左から右への深さ優先検索として説明されています。このコードでこれをテストしようとしました:

class A(object):
def __init__(self):
    print "Initialized A"

class B(A):
    def test():
        print "Initialized B"

class C(A):
    def __init__(self):
        print "Initialized C"

class D(B, C):
    def __init__(self):
        super(D, self).__init__()
        print "Initialized D"

オブジェクト D のインスタンスを作成すると:

D()

私は結果を得る:

Initialized C
Initialized D

MRO は深さ優先であるため、"Initialized A"、"Initialized D" の出力を期待していましたが、初期化は最初に B で検索されます。 B (つまり A) の基本クラスの関数。Aの代わりにCのinit-functionを取得する理由を説明してもらえますか?

4

2 に答える 2

5

の MRODは次のとおりです。

print(D.mro())
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>]

そう

super(D, self).__init__()

after__init__の最初のクラスのメソッドを探します。には がないため、 でメソッドを探します。が見つかり、したがってself.__class__.mro()DB__init____init__CC.__init__

super(D, self).__init__()

を呼び出しますC.__init__(self)

superが にアクセスしようとしていないことに注意してくださいgetattr(B, __init__)。むしろ、で探してい'__init__'ますB.__dict__

于 2013-01-04T22:20:23.250 に答える
4

あなたのクラスはから継承しobjectているため、クラシック クラスではありません。新しいスタイルのクラスです。(new-style クラスを継承するクラスも new-style クラスです。)

superいずれにせよ、従来のクラスでは使用できないことに注意してください。あなたが引用した「左から右への深さ」ルールは、インスタンスで直接定義されていない属性にアクセスしようとしたときに、基本クラスが検索される順序の属性検索ルールにすぎません。従来のクラスは MRO 自体を提供しません --- 特定のスーパークラスを明示的に参照せずに、属性の「スーパークラス値」にアクセスする方法はありません。

于 2013-01-04T22:21:21.463 に答える