Python:包装递归函数

2024-09-30 16:29:12 发布

您现在位置:Python中文网/ 问答频道 /正文

如何包装递归函数,包括递归调用?例如,给定foowrap

def foo(x):
    return foo(x - 1) if x > 0 else 1

def wrap(f):
    def wrapped(*args, **kwargs):
        print "f was called"
        return f(*args, **kwargs)

    return wrapped

wrap(foo)(x)只输出第一个调用的"f was called"。递归调用仍然是地址foo()。在

我不介意猴子修补,或者在里面乱翻。我不打算在下一个核弹头处理程序中添加这个代码,所以即使这是个坏主意,我也希望达到效果。在

编辑:例如,修补foo.func_globals来覆盖foo.__name__是否有效?如果总是这样,有什么副作用我应该注意吗?在


Tags: returniffoo地址defargselsekwargs
2条回答

如果您使用包装器函数作为装饰器,它就可以工作。在

def wrap(f):
    def wrapped(*args, **kwargs):
        print "f was called"
        return f(*args, **kwargs)

    return wrapped

@wrap
def foo(x):
    return foo(x - 1) if x > 0 else 1

原因是在您的示例中,只调用wrap函数的结果一次。如果您使用它作为装饰器,它实际上会用修饰函数替换模块名称空间中foo的定义,因此它的内部调用解析为包装的版本。在

用类而不是函数包装函数:

>>> def foo(x):
...     return foo(x-1) if x > 0 else 1
...
>>> class Wrap(object):
...     def __init__(self, f): self.f = f
...     def __call__(self, *args, **kwargs):
...         print "f called"
...         return self.f(*args, **kwargs)
...
>>> foo = Wrap(foo)
>>> foo(4)
f called
1

相关问题 更多 >