2010-06-08 21 views
15

Aiuta un ragazzo. Non riesco a convincere un decoratore a lavorare con l'ereditarietà. Abbattuto il più semplice esempio nel mio spazio di lavoro di scratch. Ancora non riesco a farlo funzionare.Decoratori ed ereditarietà Python

class bar(object): 
    def __init__(self): 
     self.val = 4 
    def setVal(self,x): 
     self.val = x 
    def decor(self, func): 
     def increment(self, x): 
      return func(self, x) + self.val 
     return increment 

class foo(bar): 
    def __init__(self): 
     bar.__init__(self) 
    @decor 
    def add(self, x): 
     return x 

Spiacenti, il nome "decoro" non è definito.

Ok, che ne dite di @bar.decor? TypeError: il metodo non associato "decor" deve essere chiamato con una istanza della barra come primo argomento (invece l'istanza della funzione)

Ok, che ne dici di @self.decor? Il nome "self" non è definito.

Ok, che ne dici di @foo.decor?! Il nome "pippo" non è definito.

AaaaAAaAaaaarrrrgggg ... Cosa sto sbagliando?

+0

Nel tuo esempio, si potrebbe avere 'tornare x + self.val' per la definizione di' 'add' in foo'. Non potresti farlo nel tuo codice attuale? –

+0

Questo è un codice di esempio distillato che evidenzia il problema che stavo affrontando. Se il codice fosse così semplice, allora sì. Tuttavia, non lo è. – wheaties

risposta

19

Definire decor come un metodo statico e utilizzare la forma @bar.decor:

class bar(object): 
    def __init__(self): 
     self.val = 4 
    def setVal(self,x): 
     self.val = x 
    @staticmethod 
    def decor(func): 
     def increment(self, x): 
      return func(self, x) + self.val 
     return increment 

class foo(bar): 
    def __init__(self): 
     bar.__init__(self) 
    @bar.decor 
    def add(self, x): 
     return x 
+0

Funziona ancora meglio perché 'self' non è usato in entrambe le definizioni di funzione. – exupero

+1

@EShull: in realtà, 'decor' può essere un metodo statico, nonostante il riferimento 'self'. 'self' è referenziato solo all'interno di 'increment()', e quando si richiama 'f.add (10)' su un'istanza 'foo', il parametro' self' dentro' increment() 'farà riferimento a' f', e il l'incremento funzionerà come previsto. –

+0

Sembra che funzionerà. Devo lasciare il lavoro, ma se lo fa, ho intenzione di contrassegnare questo come la risposta. Grazie! – wheaties