Chiamare il metodo di classe di una classe base in Python


105

Considera il codice seguente:

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 faccio a chiamare Base.do?

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

Nell'esempio sopra, Base.do(a)stampa Baseclass invece di Derivedclass.


Risposte:


121

Se stai usando una classe di nuovo stile (cioè deriva da objectin Python 2, o sempre in Python 3), puoi farlo in super()questo modo:

super(Derived, cls).do(a)

Questo è il modo in cui richiameresti il ​​codice nella versione del metodo della classe base (cioè print cls, a), dalla classe derivata, clsessendo impostato sulla classe derivata.


8
uh uh .. come mai non mi è mai supercapitato di poterlo usare anche sui metodi di lezione.
Sridhar Ratnakumar

questo funziona (per una limitazione imposta da super) solo se la base deriva da oggetto, giusto? cosa fai se non è così?
ars-longa-vita-brevis

Sì, 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 di nuovo stile, IIRC) Altrimenti devi fare Base.do(self, ...), penso, codificando così il nome della superclasse.
David Z,

Dentro Derived.do(), non è clslo stesso di Derived?
Ray

@Ray Se è effettivamente un'istanza di Derivedma non di una sottoclasse, allora sì.
David Z

15

è passato un po 'di tempo, ma penso di aver trovato una risposta. Quando si decora un metodo in modo che diventi un metodo di classe, il metodo non associato 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')

2
Nota: questo approccio funziona per le classi vecchio stile in cui super () non funziona
Alex Q

2
Disponibile anche come __func__in Python 2.7 e 3
dtheodor

-3

Questo funziona per me:

Base.do('hi')

9
L' clsargomento sarà quindi vincolato a Baseinvece diDerived
Sridhar Ratnakumar

ciò che funziona per me è questo - che assomiglia (molto) alla risposta di Ned: dove self deriva da QGraphicsView che ha paintEvent (QPaintEvent) def paintEvent (self, qpntEvent): print dir (self) QGraphicsView.paintEvent (self, qpntEvent)
user192127
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.