2009-08-12 21 views
74

Si consideri il seguente codice:Chiamata classmethod di una classe base in 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 

Da Derived.do, come mi chiamo Base.do?

Normalmente userei super o anche il nome della classe base direttamente se questo è un normale metodo di oggetto, ma a quanto pare non riesco a trovare un modo per chiamare il metodo di classe nella classe base.

Nell'esempio precedente, Base.do(a) stampa classe Base anziché Derived.

+0

correlati: [Come chiamare il metodo di una classe genitore dalla classe bambino in Python?] (Http://stackoverflow.com/q/805066/95735) –

risposta

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

EDIT: Oh, aspetta un minuto ... non è chiaro esattamente quello che stai chiedendo. Questo è come si invoca il codice nella versione del metodo della classe base, dalla classe derivata.

+5

uh uh .. come mai non mi è mai venuto in mente che io possa usare 'super' anche su classmethods. –

+0

funziona solo (a causa di una limitazione imposta da super) se la base deriva dall'oggetto, giusto? cosa fai se non è il caso? –

+0

Sì, questo funziona solo per le classi di nuovo stile, che derivano da 'object'. (almeno in Python 2, ma in Py3 penso che tutte le classi siano in stile nuovo, IIRC) Altrimenti devi fare 'Base.do (self, ...)', penso, quindi codificare il nome del superclasse. –

-2

questo funziona per me:

Base.do('hi') 
+7

L'argomento 'cls' sarà quindi associato a' Base' invece di 'Derived' –

+0

ciò che funziona per me è questo - che sembra (molto) come la risposta di Ned: dove self deriva da QGraphicsView che ha paintEvent (QPaintEvent) def paintEvent (self, qpntEvent): stampa dir (auto) QGraphicsView.paintEvent (auto, qpntEvent) – user192127

10

questo è stato un po ', ma penso che forse ho trovato una risposta. Quando si decorare un metodo per diventare un classmethod il metodo non legato originale viene memorizzato in una proprietà denominata '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: Questo approccio funziona per le classi di vecchio stile dove super() non funziona –

+1

disponibile anche come '__func__' in python 2.7 e 3 – dtheodor

Problemi correlati