2012-07-31 13 views
17

Ho una classe con un motivo ripetitivo noioso sulle loro funzioni e volevo trasformare questo modello in un decoratore. Ma il fatto è che questo decoratore deve accedere ad alcuni attributi dell'istanza corrente, quindi ho voluto trasformarlo in un metodo in questa classe. Sto avendo dei problemi con quello.Un metodo può essere un decoratore di un altro metodo della stessa classe?

Quindi, questo è simile a quello che voglio:

class DullRepetitiveClass: 
    def __init__(self, nicevariable): 
     self.nicevariable = nicevariable 

    def mydecorator(self, myfunction): 
     def call(*args, **kwargs): 
      print "Hi! The value of nicevariable is %s"%(self.nicevariable,) 
      return myfunction(*args, **kwargs) 
     return call 

    @mydecorator   #Here, comment (1) below. 
    def somemethod(self, x): 
     return x + 1 

(1) Qui è il problema. Voglio utilizzare il metodo DullRepetitiveClass.mydecorator per decorare il metodo somemethod. Ma non ho idea di come usare il metodo dall'istanza corrente come decoratore.

C'è un modo semplice per farlo?

MODIFICA: Ok, la risposta è abbastanza ovvia. Come dice Sven in basso, lo stesso decoratore trasforma il metodo. Il metodo stesso dovrebbe occuparsi di tutto ciò che riguarda l'istanza:

def mydecorator(method): 
    def call(self, *args, **kwargs): 
     print "Hi! The value of nicevariable is %s"%(self.nicevariable,) 
     return method(self, *args, **kwargs) 
    return call 


class DullRepetitiveClass: 
    def __init__(self, nicevariable): 
     self.nicevariable = nicevariable 

    @mydecorator    
    def somemethod(self, x): 
     return x + 1 
+1

Si prega di correggere il rientro. Nota inoltre che il tuo codice non contiene alcun metodo di classe. –

+0

Stai chiedendo come passare un'istanza * diversa * diversa da 'self' a' mydecorator' mentre decora 'somemethod'? – kojiro

+0

Oops. Copiare da vim e incollare al browser può essere un dolore a volte ... –

risposta

11

Il decoratore ottiene un solo parametro - la funzione o il metodo decora. Non viene passata un'istanza come parametro self - al momento in cui viene chiamato il decoratore, nemmeno la classe è stata creata, per non parlare di un'istanza della classe. L'istanza verrà passata come primo argomento alla funzione decorata, quindi è necessario includere self come primo parametro nell'elenco dei parametri di call().

Non vedo la necessità di includere il decoratore nello scope di classe. Puoi farlo, ma puoi anche averlo allo scopo del modulo.

+0

Dannazione, è così ovvio. Il decoratore riceve solo il metodo e restituisce un metodo modificato. Il metodo è il ragazzo che deve affrontare l'istanza ... dannazione. Così ovvio. –

+0

Cosa succede se il tuo decoratore ha bisogno di usare i membri della classe? O è solo una cattiva idea/modello? – aaronlevin

+0

@weirdcanada: Poiché la classe non è ancora stata creata al momento della chiamata del decoratore, non è possibile accedere ai suoi membri in modo normale. Puoi fare alcuni hack per ovviare a questo (cose come passare 'locals()' come parametro per il decoratore), ma sono piuttosto non ovvi, e non riesco a pensare ad una buona ragione per farlo. –

Problemi correlati