新来的.我也是(非常)新的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()
这是我系统上的输出:
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)
那么为什么装饰的调用永远不会下降到孙子节点?我显然错过了一些关于语法的东西......
在装饰,你遍历节点的孩子和调用原始,非递归method
他们
method(child, *args, **kwargs)
所以你只会深入一层.尝试用.替换该行
map_children(method)(child, *args, **kwargs)
并且您将获得与手动递归版本相同的输出.