【问题标题】:python decorators and methodspython装饰器和方法
【发布时间】:2010-10-16 12:26:30
【问题描述】:

这里是新的。我也是(非常)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()

这是我系统上的输出:

在[]:testcase.runme() **********装饰师的结果********** 父母 child1(父母的孩子) child2(父母的孩子) **********手工结果********** 父母 child1(父母的孩子) 孙子(child1 的孩子) child2(父母的孩子)

那么为什么修饰的调用永远不会下降到孙节点?我显然遗漏了一些关于语法的东西......

【问题讨论】:

    标签: python metaprogramming decorator


    【解决方案1】:

    在装饰器中,您循环遍历节点的子节点并在它们上调用原始非递归method

    method(child, *args, **kwargs)
    

    所以你只会深入一层。尝试用

    替换该行
    map_children(method)(child, *args, **kwargs)
    

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

    【讨论】:

    • 谢谢!知道它必须是那样的。我用@ 表示法尝试了这个,但它不起作用(显然),而且我找不到正确的语法。然后我设法说服自己它正在改变实际的方法,所以没关系。我必须停止将其视为“正确的”宏。
    • 我认为如果 Node 是子类并且子类有自己的方法版本,这种方法不会达到您的预期......
    猜你喜欢
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 2022-01-18
    • 2012-02-09
    • 2018-07-14
    • 2016-02-10
    • 2012-09-11
    • 1970-01-01
    相关资源
    最近更新 更多