2009-03-30 26 views
7

Mới tại đây. Ngoài ra tôi (rất) mới với python và cố gắng hiểu hành vi sau đây. Ai đó có thể giải thích cho tôi tại sao hai phương pháp trong ví dụ này có đầu ra khác nhau?Trang trí và phương pháp python

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() 

Đây là kết quả trên hệ thống của tôi:

 
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) 

Vậy tại sao không gọi được trang trí không bao giờ xuống đến nút cháu? Tôi rõ ràng là thiếu một cái gì đó về cú pháp ...

Trả lời

7

Trong trang trí, bạn đang Looping trên trẻ em của nút và gọi gốc, không đệ quy method trên chúng

method(child, *args, **kwargs) 

vì vậy bạn' sẽ chỉ đi sâu một cấp. Hãy thử thay thế dòng đó bằng

map_children(method)(child, *args, **kwargs) 

và bạn sẽ nhận được kết quả tương tự như phiên bản đệ quy thủ công.

+1

Cảm ơn! Biết rằng nó phải giống như thế. Tôi đã thử điều này với ký hiệu @ nhưng nó không hoạt động (rõ ràng), và tôi không tìm được cú pháp đúng. Sau đó, tôi đã thuyết phục bản thân mình rằng nó đã biến đổi phương pháp thực tế, vì vậy không thành vấn đề. Tôi phải ngừng nghĩ về nó như những macro "thích hợp". –

+0

Tôi nghĩ rằng cách tiếp cận này sẽ không làm những gì bạn mong đợi nếu Node được phân lớp và lớp con có phiên bản riêng của phương thức ... – simon

Các vấn đề liên quan