2009-03-30 14 views
7

Nowe tutaj. Ponadto jestem (bardzo) nowy w python i próbuję zrozumieć następujące zachowanie. Czy ktoś może mi wyjaśnić, dlaczego dwie metody w tym przykładzie mają różne wyniki?Dekoratorzy pytonów i metody

def map_children(method): 
    def wrapper(self,*args,**kwargs): 
     res = method(self,*args,**kwargs) 
     for child in self._children: 
      method(child,*args,**kwargs)    
     return res 
    return wrapper 

class Node(object): 

    def __init__(self,name,parent=None): 
     self._namestring = name 
     if parent: 
      self._parent = parent 

     self._children = [] 

    @map_children 
    def decorated(self): 
     if hasattr(self,'_parent'): 
      print '%s (child of %s)'%(self._namestring,self._parent._namestring) 
     else: 
      print '%s'% self._namestring 

    def undecorated(self): 
     if hasattr(self,'_parent'): 
      print '%s (child of %s)'%(self._namestring,self._parent._namestring) 
     else: 
      print '%s'% self._namestring 

     for child in self._children: 
      child.undecorated() 


def runme(): 
    parent = Node('parent') 

    child1 = Node('child1',parent) 
    child2 = Node('child2',parent) 
    grandchild = Node('grandchild',child1) 
    child1._children.append(grandchild) 
    parent._children.append(child1) 
    parent._children.append(child2) 

    print '**********result from decorator**********' 
    parent.decorated() 

    print '**********result by hand**********' 
    parent.undecorated() 

Oto wynik w moim systemie:

 
In[]:testcase.runme() 
**********result from decorator********** 
parent 
child1 (child of parent) 
child2 (child of parent) 
**********result by hand********** 
parent 
child1 (child of parent) 
grandchild (child of child1) 
child2 (child of parent) 

Więc dlaczego urządzone wezwanie nigdy schodzić do węzła wnuka? Ja oczywiście brakuje czegoś o składni ...

Odpowiedz

7

W dekoratora, jesteś zapętlenie nad dziećmi węzła i wywołanie oryginalny, nierekursywnych method na nich

method(child, *args, **kwargs) 

więc” Zajmę tylko jeden poziom głębokości. Spróbuj zastąpić tę linię wartością

, a otrzymasz te same wyniki co ręczna wersja rekursywna.

+1

Dzięki! Wiedział, że to musiało być coś takiego. Próbowałem tego z notacją @, ale to nie działało (oczywiście) i nie mogłem znaleźć odpowiedniej składni. Wtedy udało mi się przekonać samą siebie, że zmieniło to właściwą metodę, więc nie powinno to mieć znaczenia. Muszę przestać myśleć o tym jak o "właściwych" makrach. –

+0

Myślę, że to podejście nie zrobi tego, czego się oczekuje, jeśli węzeł jest podklasowany, a podklasa ma własną wersję metody ... – simon