Frage Aufruf der Klassenmethode einer Basisklasse in Python


Betrachten Sie den folgenden Code:

class Base(object):

    @classmethod
    def do(cls, a):
        print cls, a

class Derived(Base):

    @classmethod
    def do(cls, a):
        print 'In derived!'
        # Base.do(cls, a) -- can't pass `cls`
        Base.do(a)

if __name__ == '__main__':
    d = Derived()
    d.do('hello')

> $ python play.py  
> In derived! 
> <class '__main__.Base'> msg

Von Derived.do, wie rufe ich an Base.do?

Ich würde normalerweise verwenden super oder auch direkt der Name der Basisklasse, wenn es sich um eine normale Objektmethode handelt, aber anscheinend kann ich die Klassenmethode in der Basisklasse nicht aufrufen.

Im obigen Beispiel Base.do(a) Drucke Base Klasse statt Derived Klasse.


76
2017-08-12 23:07


Ursprung


Antworten:


Wenn Sie eine neue Stilklasse verwenden (also von object in Python 2 oder immer in Python 3), können Sie es mit tun super() so was:

super(Derived, cls).do(a)

Auf diese Weise würden Sie den Code in der Version der Basisklasse der Methode aufrufen (d. H. print cls, a), von der abgeleiteten Klasse mit cls auf die abgeleitete Klasse gesetzt werden.


86
2017-08-12 23:09



Das ist eine Weile her, aber ich glaube, ich habe eine Antwort gefunden. Wenn Sie eine Methode dekorieren, um eine Klassenmethode zu werden, wird die ursprüngliche ungebundene Methode in einer Eigenschaft mit dem Namen 'im_func' gespeichert:

class Base(object):
    @classmethod
    def do(cls, a):
        print cls, a

class Derived(Base):

    @classmethod
    def do(cls, a):
        print 'In derived!'
        # Base.do(cls, a) -- can't pass `cls`
        Base.do.im_func(cls, a)

if __name__ == '__main__':
    d = Derived()
    d.do('hello')

10
2018-04-15 21:01



Das funktioniert für mich:

Base.do('hi')

-2
2017-08-12 23:12