0

そのため、私は Python 2.7 の多重継承と MRO の素晴らしい世界について少し調査を行っており、読みながらさまざまな例を試していたところ、本当に困惑するものに出会いました。

これで、古典的なダイヤモンド MI の例が得られました。

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

class B(A):
    pass

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

class D(B, C):
    pass

instance = D()

私が読んだすべての MRO リソースで、この例には DBCA の MRO が含まれている必要があるため、D を初期化すると "C" が出力されますが、代わりに "A" が出力されます。奇妙なことに、A、B、C、または D の定義をそのようなもののサブクラスに変更すると、int「C」を出力するという予想される動作が得られます

基本クラスがプリミティブ型であるかどうかによって、クラス構造の MRO の動作が異なるのはなぜですか? これはバグですか?

4

1 に答える 1

1

これを入力しているときに、MRO についてもう少し読んだところ、(大雑把に理解している限り) python には古いスタイル (2.2 より前) のクラスと新しいスタイルのクラスがあることがわかりました。古いスタイルの MRO は左から右への深さ優先 (DBAC を与える) であり、新しいスタイルは C3 と呼ばれるアルゴリズムであり、これはすべての python 2.7 クラスが使用すると想定したものです。この継承階層を持つ新しいスタイル クラスに C3 アルゴリズムを適用すると、DBCA が得られます。基本的に 2.7 では、継承するクラスObjectは new-style であり、そうでないクラスは old-style です。Objectとにかく、すべてのクラスが継承する 3.0 と 2.7 を混同していました。したがってD、新しいスタイルのクラスから継承されたベースのいずれかがD新しいスタイルの MRO を提供する場合D、この例では古いスタイルの MRO になります。

これは、もっと多くの人が知っておくべきクールなちょっとした癖です。それが理にかなっていることを願っています。

于 2015-10-21T09:08:10.667 に答える