2010-08-06 10 views
5

come si fa ad accedere a un decoratore da una classe base in un bambino?Accesso a un decoratore in una classe genitore dal figlio in Python

Ho assunto (erroneamente) che il ffg. avrebbe funzionato:

class baseclass(object): 
    def __init__(self): 
     print 'hey this is the base' 

    def _deco(func): 
     def wrapper(*arg): 
      res = func(*arg) 
      print 'I\'m a decorator. This is fabulous, but that colour, so last season sweetiedarling' 
      return res 
     return wrapper 

    @_deco 
    def basefunc(self): 
     print 'I\'m a base function' 

Questa classe funziona bene, ma poi ho creare una classe figlia eredita da questo:

class otherclass(baseclass): 
    def __init__(self): 
     super(otherclass, self).__init__() 
     print 'other class' 


    @_deco 
    def meh(self): 
     print 'I\'m a function' 

Questo non sarà nemmeno importare correttamente, per non correre da soli. @_deco non è definito. Provando baseclass._deco si genera un errore _deco() del metodo non associato, che non è davvero sorprendente.

Qualsiasi idea di come fare questo, mi piacerebbe davvero per incapsulare il decoratore nella classe, ma io non sono sposato l'idea e avevo bisogno di chiamarlo nella base & la classe figlia.

+0

Il caso di utilizzo per questo è un decoratore di temporizzazione per un controller piloni. Quindi deve essere accessibile dalla base perché ci sono funzioni che devono essere programmate e funzioni nella classe figlio che devono essere sincronizzate. Immagino che il modo più semplice sarebbe quello di strapparlo dalla classe. – dochead

+0

Potresti correggere la tua formattazione? I 'def __init__' della tua classe hanno la stessa indentazione della definizione della classe. – MattH

risposta

7
class baseclass(object): 
    def __init__(self): 
     print 'hey this is the base' 

    def _deco(func): 
     def wrapper(*arg): 
      res = func(*arg) 
      print 'I\'m a decorator. This is fabulous, but that colour, so last season sweetiedarling' 
      return res 
     return wrapper 

    @_deco 
    def basefunc(self): 
     print 'I\'m a base function' 

    @_deco 
    def basefunc2(self): 
     print "I'm another base function" 

    #no more uses of _deco in this class 
    _deco = staticmethod(_deco) 
    # this is the key. it must be executed after all of the uses of _deco in 
    # the base class. this way _deco is some sort weird internal function that 
    # can be called from within the class namespace while said namespace is being 
    # created and a proper static method for subclasses or external callers. 


class otherclass(baseclass): 
    def __init__(self): 
     super(otherclass, self).__init__() 
     print 'other class' 


    @baseclass._deco 
    def meh(self): 
     print 'I\'m a function' 
+0

+1; molto meglio della mia risposta (ora cancellata). – bernie

+0

Favoloso, ne avrò un po ', è proprio così in questa stagione, sweetiedarling. (Ho pensato di andare con il tema.) – dochead

+0

Ho anche scoperto che puoi anche usare @staticmethod decorator, ma SOLO se non dichiari @_deco nella classe base (quale sei). Quindi questa soluzione sembra adattarsi meglio alla domanda che viene posta. –

Problemi correlati