Manchmal müssen Texte eher für den Geschmack der Idee als für die Details gelesen werden. Dies ist einer dieser Fälle.
Auf der verlinkten Seite sollten die Beispiele 2.5, 2.6 und 2.7 alle eine Methode verwenden do_your_stuff. (Das heißt, do_somethingsollte geändert werden do_your_stuff.)
Darüber hinaus muss, wie Ned Deily betonte , A.do_your_stuffeine Klassenmethode sein.
class A(object):
@classmethod
def do_your_stuff(cls):
print 'This is A'
class B(A):
@classmethod
def do_your_stuff(cls):
super(B, cls).do_your_stuff()
B.do_your_stuff()
super(B, cls).do_your_stuff
gibt eine gebundene Methode zurück (siehe Fußnote 2 ). Da clsals zweites Argument an übergeben wurde super(), wird es clsan die zurückgegebene Methode gebunden. Mit anderen Worten, clswird als erstes Argument an die Methode do_your_stuff()der Klasse A übergeben.
Um es noch einmal zu wiederholen: Bewirkt, super(B, cls).do_your_stuff()dass Adie do_your_stuffMethode von aufgerufen wird, wobei clsals erstes Argument übergeben wird. Damit das funktioniert, muss A's
do_your_stuffeine Klassenmethode sein. Die verlinkte Seite erwähnt das nicht, aber das ist definitiv der Fall.
PS. do_something = classmethod(do_something)ist die alte Art, eine Klassenmethode zu erstellen. Die neue (er) Möglichkeit besteht darin, den @ classmethod-Dekorator zu verwenden.
Beachten Sie, dass super(B, cls)nicht durch ersetzt werden kann super(cls, cls). Dies könnte zu Endlosschleifen führen. Zum Beispiel,
class A(object):
@classmethod
def do_your_stuff(cls):
print('This is A')
class B(A):
@classmethod
def do_your_stuff(cls):
print('This is B')
super(cls, cls).do_your_stuff()
class C(B):
@classmethod
def do_your_stuff(cls):
print('This is C')
super(cls, cls).do_your_stuff()
C.do_your_stuff()
wird erhöhen RuntimeError: maximum recursion depth exceeded while calling a Python object.
Wenn clsist C, dann super(cls, cls)sucht C.mro()für die Klasse , die nach kommt C.
In [161]: C.mro()
Out[161]: [__main__.C, __main__.B, __main__.A, object]
Da diese Klasse B, wann clsist C, super(cls, cls).do_your_stuff() immer aufruft B.do_your_stuff. Da super(cls, cls).do_your_stuff()innen aufgerufen wird B.do_your_stuff, rufen Sie am Ende B.do_your_stuffin einer Endlosschleife auf.
In Python3 wurde die 0-Argument-Form vonsuper hinzugefügt, damit super(B, cls)sie durch ersetzt werden kann super(), und Python3 wird aus dem Kontext herausfinden, dass super()in der Definition von class Bgleich sein sollte super(B, cls).
Aber unter keinen Umständen ist super(cls, cls)(oder aus ähnlichen Gründen super(type(self), self)) jemals richtig.