2009-08-12 12 views
74

Considere el siguiente código:Calling classmethod de una clase 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, Como llamar en Base.do?

Normalmente utilizaría super o incluso el nombre de la clase base directamente si este es un método de objeto normal, pero aparentemente no puedo encontrar la manera de llamar al método de clase en la clase base.

En el ejemplo anterior, Base.do(a) imprime Base clase en lugar de Derived clase.

+0

relacionadas: [Cómo llamar el método de una clase padre de la clase infantil en Python?] (Http://stackoverflow.com/q/805066/95735) –

Respuesta

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

EDITAR: Oh, espera un minuto ... No es claro exactamente lo que estás pidiendo. Así es como invocaría el código en la versión de la clase base del método, desde la clase derivada.

+5

eh uh ... ¿cómo es que nunca se me ocurrió que puedo usar 'super' en classmethods también? –

+0

esto solo funciona (debido a una limitación impuesta por super) si la base se deriva del objeto, ¿verdad? ¿Qué haces si ese no es el caso? –

+0

Sí, esto solo funciona para las clases de nuevo estilo, que se derivan de 'object'. (al menos en Python 2, pero en Py3 creo que todas las clases son de estilo nuevo, IIRC) De lo contrario, tienes que hacer 'Base.do (self, ...)', creo, codificando así el nombre del superclase. –

-2

Esto funciona para mí:

Base.do('hi') 
+7

El argumento 'cls' se enlazará con' Base' en lugar de 'Derived' –

+0

Lo que funciona para mí es esto - que se parece (mucho) a la respuesta de Ned: donde self se deriva de QGraphicsView que tiene paintEvent (QPaintEvent) def paintEvent (auto, qpntEvent): dir impresión (auto) QGraphicsView.paintEvent (auto, qpntEvent) – user192127

10

esto ha sido un tiempo, pero creo que puede haber encontrado una respuesta. Al decorar un método para convertirse en un classmethod el método no unido original se almacena en una propiedad denominada '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

Nota: Este método funciona para las clases de estilo antiguo en el super() no funciona –

+1

también disponible como '__func__' en python 2.7 y 3 – dtheodor

Cuestiones relacionadas