Ich habe Ihren Code Python3 (von print
-print()
Ändern) umgewandelt, und fügte einige weitere Tracing-Anweisungen:
class A(object):
def __init__(self):
print("A", type(self).__mro__)
super(A, self).__init__()
print("/A")
class B(object):
def __init__(self):
print("B", type(self).__mro__)
super(B, self).__init__()
print("/B")
class C(A,B):
def __init__(self):
print("C")
A.__init__(self)
print("ca/b")
B.__init__(self)
print("/C")
C()
Hier ist der Ausgang:
C
A (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
B (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
/B
/A
ca/b
B (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
/B
/C
am Ausgang suchen, können Sie den Anruf an die C.__init__
Methode sehen geschieht, und das Drucken ‚C‘. Es ruft dann A.__init__
direkt auf (was ein Fehler ist - verwenden Sie super
!).
Der Anruf A.__init__
gibt seine Nachricht aus, einschließlich des Attributs __mro__
. Sie können die Sequenz sehen: C -> A -> B -> Objekt. Dies ist wichtig, weil Aufrufe an super()
innerhalb von A.__init__
sich auf die Klasse B
beziehen. Auch Aufrufe an super
von innen C.__init__
hätten A.__init__
automatisch aufgerufen, wenn Sie sie zulassen.
Die nächste Methode, B.__init__
, wird von der super
Referenz innerhalb A.__init__
, wie erwähnt, aufgerufen. Es ruft vermutlich Object.__init__
an, die nichts ausdruckt. ;-)
Sowohl B.__init__
und A.__init__
Rückkehr sehen wir den Mittelpunkt Nachricht ca/b
, und dann direkten Aufruf an B.__init__
wird. Es wird eine Nachricht ausgedruckt, aber wieder ein Verweis auf super
Formular B.__init__
tut nichts, denn B
ist am Ende des MRO.
Der super()
Mechanismus kann mit all diesen MRO-Sachen für Sie umgehen. Sie sollten A.__init__(self)
nicht aufrufen müssen. Stattdessen können Sie nur super
Griff es lassen, innen C.__init__
, aber dies zu tun:
class C(A,B):
def __init__(self):
print("C")
super(C, self).__init__()
, die so groß ist! Vielen Dank – TreeCatCat