2010-06-08 15 views
15

Ayuda a un chico. Parece que no puede lograr que un decorador trabaje con la herencia. Búscalo al pequeño ejemplo más simple en mi espacio de trabajo de cero. Todavía parece que no puede funcionar.Python Decorators and inheritance

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 

Vaya, el nombre "decor" no está definido.

Bien, ¿qué hay de @bar.decor? TypeError: se debe llamar al método "decor" unbound con una instancia de barra como primer argumento (instancia de función got en su lugar)

Ok, ¿qué hay de @self.decor? El nombre "self" no está definido.

Ok, ¿qué hay de @foo.decor?! El nombre "foo" no está definido.

AaaaAAaAaaaarrrrgggg ... ¿Qué estoy haciendo mal?

+0

En su ejemplo, usted podría tener 'volver x + self.val' para la definición de' 'add' en foo'. ¿No podrías hacer esto en tu código real? –

+0

Este es un código de ejemplo destilado que destaca el problema al que me enfrentaba. Si el código fuera así de simple, entonces sí. Sin embargo, no lo es. – wheaties

Respuesta

19

Definir decor como un método estático y utiliza el formulario de @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

Esto funciona aún mejor porque 'self' no se usa en ambas definiciones de funciones. – exupero

+1

@EShull: en realidad, 'decor' puede ser un método estático, a pesar de la referencia' self'. 'self' solo se referencia dentro de' increment() ', y cuando se invoca' f.add (10) 'en una instancia' foo', el parámetro 'self' dentro de' increment() 'hará referencia a' f', y el el incremento funcionará como se espera. –

+0

Parece que va a funcionar. Tengo que dejar el trabajo, pero si lo hace, voy a marcar esto como la respuesta. ¡Gracias! – wheaties