Python decorators and methods

New here. I am also (very) new to python and trying to understand the following behavior. Can someone explain to me why the two methods in this example have different output?

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

Here is the output on my system:

 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)

So why does the decorated bell never sink to the node's grandson? I am clearly missing something about the syntax ...

+7
python decorator metaprogramming
source share
1 answer

In the decorator, you iterate over the children of a node and call the original, non-recursive method on them

 method(child, *args, **kwargs) 

therefore you will only go one level. Try replacing this line with

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

and you will get the same result as the manual recursive version.

+7
source share

All Articles