[英]Python: wrapping recursive functions
How can I wrap a recursive function, recursive calls included? 如何包装递归函数,包括递归调用? For example, given foo
and wrap
: 例如,给定foo
和wrap
:
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)
will only output "f was called"
with the first call. wrap(foo)(x)
只会在第一次调用时输出"f was called"
。 Recursive calls still address foo()
. 递归调用仍然解决foo()
。
I don't mind monkey patching, or poking around internals. 我不介意猴子修补,或在内部戳。 I'm not planning to add this code to the next nuclear warhead handling program, so even if it's a bad idea, I'd like to achieve the effect. 我不打算将这个代码添加到下一个核弹头处理程序中,所以即使这是一个坏主意,我也想实现这个效果。
Edit : for example, would patching foo.func_globals
to override foo.__name__
work? 编辑 :例如,修补foo.func_globals
以覆盖foo.__name__
工作? If it always does, any side-effects I should be minding? 如果它总是这样,我应该注意任何副作用?
It works if you use your wrapper function as a decorator. 如果您使用包装器函数作为装饰器,它可以工作。
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
Reason being that in your example, you're only calling the result of the wrap
function once. 原因是在您的示例中,您只调用一次wrap
函数的结果。 If you use it as a decorator it actually replaces the definition of foo
in the module namespace with the decorated function, so its internal call resolves to the wrapped version. 如果您将它用作装饰器,它实际上将模块命名空间中的foo
定义替换为装饰函数,因此其内部调用将解析为包装版本。
Wrap the function with a class, rather than a function: 使用类而不是函数包装函数:
>>> 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.