2010-06-08 10 views
15

Pomóż facetowi. Nie można dostać dekoratora do pracy z dziedziczeniem. Zepsułem to do najprostszego małego przykładu w moim roboczym obszarze roboczym. Nadal wydaje się, że nie działa.Dekoratory Python i dziedziczenie

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 

Ups, nazwa "decor" nie jest zdefiniowana.

Okay, a może o @bar.decor? TypeError: niezwiązana metoda "decor" musi zostać wywołana z instancją paska jako pierwszym argumentem (zamiast tego otrzymała instancję funkcji)

OK, a może o @self.decor? Nazwa "self" nie jest zdefiniowana.

OK, a może około @foo.decor?! Nazwa "foo" nie jest zdefiniowana.

AaaaAAaAaaaarrrrgggg ... Co robię źle?

+0

W przykładzie, można mieć 'powrócić x + self.val' dla definicji' add' w 'foo'. Czy nie zrobiłbyś tego w swoim prawdziwym kodzie? –

+0

To jest destylowany kod przykładowy, podświetlający problem, z którym miałem do czynienia. Jeśli kod byłby taki prosty, to tak. Jednak tak nie jest. – wheaties

Odpowiedz

19

Definiowanie decor jako metoda statyczna i skorzystać z formularza @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

Działa to jeszcze lepiej, ponieważ 'self' nie jest używane w obu definicjach funkcji. – exupero

+1

@EShull: Właściwie, 'decor' może być metodą statyczną, pomimo odniesienia' self'. 'self' jest odwoływane tylko wewnątrz' increment() ', a podczas wywoływania' f.add (10) 'w instancji' foo', parametr 'self' wewnątrz' increment() 'odwołuje się do' f', a inkrementacja zadziała zgodnie z oczekiwaniami. –

+0

Wygląda na to, że zadziała. Muszę opuścić pracę, ale jeśli tak, zamierzam oznaczyć to jako odpowiedź. Dzięki! – wheaties