Reputation:
New here. Also I'm (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 call never descend to the grandchild node? I'm obviously missing something about the syntax...
Upvotes: 8
Views: 6966
Reputation: 75785
In the decorator, you are looping over the node's children and calling the original, non-recursive method
on them
method(child, *args, **kwargs)
so you'll only go one level deep. Try replacing that line with
map_children(method)(child, *args, **kwargs)
and you'll get the same output as the manual recursive version.
Upvotes: 7