2009-08-12 5 views
74

Consultez le code suivant:Appeler un classmethod de la classe de base en Python

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 

De Derived.do, comment dois-je appeler Base.do?

J'utiliserais normalement super ou même le nom de la classe de base directement s'il s'agit d'une méthode d'objet normal, mais apparemment je n'arrive pas à trouver un moyen d'appeler le classmethod dans la classe de base.

Dans l'exemple ci-dessus, Base.do(a) imprime la classe Base au lieu de la classe Derived.

+0

connexes: [Comment appeler la méthode d'une classe parente de la classe des enfants en python?] (Http://stackoverflow.com/q/805066/95735) –

Répondre

83
super(Derived, cls).do(a) 

EDIT: Oh, attendez une minute ... On ne sait pas exactement ce que vous demandez. C'est ainsi que vous invoqueriez le code dans la version de la méthode de la classe de base, à partir de la classe dérivée.

+5

euh euh ... comment se fait-il qu'il ne m'est jamais arrivé que je puisse utiliser 'super' sur classmethods aussi. –

+0

cela fonctionne seulement (en raison d'une limitation imposée par super) si la base dérive de l'objet, non? que faites-vous si ce n'est pas le cas? –

+0

Oui, cela ne fonctionne que pour les classes new-style, qui dérivent de 'object'. (au moins dans Python 2, mais dans Py3 je pense que toutes les classes sont de style nouveau, IIRC) Sinon, vous devez faire 'Base.do (self, ...)', je pense, codant ainsi dur le nom de la superclasse. –

-2

Cela fonctionne pour moi:

Base.do('hi') 
+7

L'argument 'cls' sera alors lié à' Base' au lieu de 'Derived' –

+0

ce qui fonctionne pour moi est ceci - qui ressemble (beaucoup) à la réponse de Ned: où l'auto dérive de QGraphicsView qui a paintEvent (QPaintEvent) def paintEvent (auto, qpntEvent): print dir (auto) QGraphicsView.paintEvent (auto, qpntEvent) – user192127

10

cela a été un certain temps, mais je crois que je l'ai trouvé une réponse. Lorsque vous décorez une méthode pour devenir un classmethod la méthode originale non reliée est stocké dans une propriété nommée « im_func »:

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') 
+1

note: Cette approche fonctionne pour les classes de style ancien où super() ne fonctionne pas –

+1

aussi disponible '__func__' en python 2.7 et 3 – dtheodor

Questions connexes