【问题标题】:How To make decorator get invoked on a recursive function call?如何在递归函数调用中调用装饰器?
【发布时间】:2026-01-20 04:35:01
【问题描述】:

所以这里是这个问题的扩展:https://*.com/a/37568895/2290820 关于如何选择性地启用或禁用函数的装饰器。

在这些行中,我想出了这样的方法来让装饰器在递归调用中被调用:

def deco(f):
    def fattr(attr):
        f.attr = attr
        def closure(*args):
            f(*args)
        f.unwrap = f
        f.closure = closure
        return f
    return fattr

@deco
def printa(x):
    if x > 1:
        print x
        return printa(x-1)
    else:
        print x
    return

printa({1:1})(5)

# do the same call w/o deocorator
def finta(x):
    if x > 1:
        print x
        return finta(x-1)
    else:
        print x
    return

finta(5) # this works

在递归函数上试验装饰器。显然,printa 递归版本的行为不应该是这样。

我可以的

g = printa({1:1})
g.closure(5)

打开装饰器选项或不使用该选项。无论如何,无论设计好坏,我怎样才能让装饰器在递归调用中被调用?

【问题讨论】:

  • 我不知道为什么这被选为题外话。这是一个如此热门的话题!

标签: python recursion python-decorators


【解决方案1】:

在您的 deco 中,您有一个分配 f.attr = attr 在第一次递归调用后“吃掉”您的论点。你应该这样修改你的递归调用:

def deco(f):
    def fattr(attr):
        f.attr = attr
        def closure(*args):
            f(*args)
        f.unwrap = f
        f.closure = closure
        return f
    return fattr

@deco
def printa(x):
    if x > 1:
        print x
        return printa(None)(x-1) # None will be assigned to f.attr
    else:
        print x
    return

printa({1:1})(5)

5
4
3
2
1

【讨论】: