How can I wrap a recursive function, recursive calls included? For example, given foo
and 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. Recursive calls still address 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? 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. 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With