Python:包装递归函数

sle*_*ica 8 python higher-order-functions

如何包装递归函数,包括递归调用?例如,给定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
Run Code Online (Sandbox Code Playgroud)

wrap(foo)(x)只会"f was called"在第一次通话时输出.递归调用仍然可以解决foo().

我不介意猴子修补,或在内部戳.我不打算将这个代码添加到下一个核弹头处理程序中,所以即使这是一个坏主意,我也想实现这个效果.

编辑:例如,修补foo.func_globals以覆盖foo.__name__工作?如果它总是这样,我应该注意任何副作用?

Kam*_*iel 10

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

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
Run Code Online (Sandbox Code Playgroud)

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