6

まず第一に、私はより良いタイトルを持っていないことをお詫びしなければなりません。より適切なものを見つけたら、自由に変更してください。

基本的に、私はPythonの多重継承の振る舞いに悩まされてきました。以前のSOの質問では、PythonのC3MROを読むように指示されました。これは、Pythonでの多重継承をよりよく理解するのに本当に役立ちます。把握したと思った瞬間、次のようなシナリオに出くわしましたが、意味がわからないようです。

class UltimateBase(object):
    def check(self):
        print 'base check'

class AMixin1(UltimateBase):
    def check(self):
        print 'check A'

class BMixin1(UltimateBase):
    def check(self):
        print 'check B'

class CMixin1(UltimateBase):
    def check(self):
        print 'check C'

class AMixin2(UltimateBase):
    def check(self):
        print 'check A'
        return super(AMixin2, self).check()

class BMixin2(UltimateBase):
    def check(self):
        print 'check B'
        return super(BMixin2, self).check()

class CMixin2(UltimateBase):
    def check(self):
        print 'check C'
        return super(CMixin2, self).check()

class MyView1(AMixin1, BMixin1, CMixin1):
    pass

class MyView2(AMixin2, BMixin2, CMixin2):
    pass

class MyView3(AMixin1, BMixin2, CMixin2):
    pass

class MyView4(AMixin2, BMixin1, CMixin2):
    pass

class MyView5(AMixin2, BMixin2, CMixin1):
    pass

class MyView6(AMixin1, BMixin1, CMixin2):
    pass

class MyView7(AMixin1, BMixin2, CMixin1):
    pass

class MyView8(AMixin2, BMixin1, CMixin1):
    pass

myview1 = MyView1()
myview2 = MyView2()
myview3 = MyView3()
myview4 = MyView4()
myview5 = MyView5()
myview6 = MyView6()
myview7 = MyView7()
myview8 = MyView8()

myview1.check()
print '------------------------'
myview2.check()
print '------------------------'
myview3.check()
print '------------------------'
myview4.check()
print '------------------------'
myview5.check()
print '------------------------'
myview6.check()
print '------------------------'
myview7.check()
print '------------------------'
myview8.check()
print '------------------------'

出力:

check A
------------------------
check A
check B
check C
base check
------------------------
check A
------------------------
check A
check B
------------------------
check A
check B
check C
------------------------
check A
------------------------
check A
------------------------
check A
check B
------------------------

出力を観察することでパターンを追跡することはできますが、この結果の背後にある理論的根拠を理解できないのはバグです。

たとえば、なぜmyview2.check()戻るのかなどの質問があります

check A
check B
check C
base check

いいえ

check A
base check

多重継承に関する重要な部分が欠けているように思えます。ギャップを埋めてください。

4

2 に答える 2

4

を呼び出すとmyview2.check()、兄弟をトラバースしてから基本クラスを呼び出します。これらのトラバーサルの 1 つがAMixin1BMixin1、またはCMixin1にヒットするたびに停止します。これらのクラスは を呼び出さないためsuper(..., self).check()です。

Benn が指摘しているように、これは公式の Python ドキュメントに記載されています。考えてみれば、ほとんどこのように機能しなければなりません。サブクラスは、サブクラスが呼び出す前に基本クラスのメソッドが呼び出されないと想定しますsuper()。そうである場合 (または、さらに悪いことに、兄弟がリストされている順序に依存する場合)、対処が非常に困難になります。

于 2012-04-05T18:48:55.203 に答える