python装饰器和方法

python装饰器和方法,python,metaprogramming,decorator,Python,Metaprogramming,Decorator,新来的。另外,我(非常)不熟悉python,并试图理解以下行为。有人能解释一下为什么这个例子中的两个方法有不同的输出吗 def map_children(method): def wrapper(self,*args,**kwargs): res = method(self,*args,**kwargs) for child in self._children: method(child,*args,**kwargs)

新来的。另外,我(非常)不熟悉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) 在[]:testcase.runme()中 **********来自装饰师的结果********** 父母亲 子女1(父母的子女) 子女2(父母的子女) **********手工结果********** 父母亲 子女1(父母的子女) 孙辈(子女1的子女) 子女2(父母的子女)
那么,为什么装饰调用从未下降到孙子节点?我显然遗漏了一些语法方面的内容…

在decorator中,您在节点的子节点上循环,并对它们调用原始的、非递归的
方法

method(child, *args, **kwargs)
所以你只会深入一层。试着把那条线换成

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

您将获得与手动递归版本相同的输出

谢谢!我知道一定是这样的。我用@notation尝试了这个方法,但是没有成功(很明显),而且我找不到正确的语法。然后我设法说服自己,这是在改变实际的方法,所以这不重要。我必须停止把它当作“正确的”宏。我认为如果节点是子类的,并且子类有它自己的方法版本,这种方法不会达到你所期望的效果。。。