Reputation:
Or a broader question: how to make a recursive function in python and, when changing its name, it only has to be changed in the declaration?
Upvotes: 9
Views: 2552
Reputation: 191
disclaimer: dirty solution but no decorator needed
import sys
def factorial(x):
_f = eval(sys._getframe().f_code.co_name)
return x if x<3 else x*_f(x-1)
>>> factorial(5)
120
Upvotes: 0
Reputation: 4445
I don't know why you'd want to do this, but nonetheless, you can use a decorator to achieve this.
def recursive_function(func):
def decorator(*args, **kwargs):
return func(*args, my_func=func, **kwargs):
return decorator
And then your function would look like:
@recursive_function
def my_recursive_function(my_func=None):
...
Upvotes: 0
Reputation:
I found a simple, working solution.
from functools import wraps
def recfun(f):
@wraps(f)
def _f(*a, **kwa): return f(_f, *a, **kwa)
return _f
@recfun
# it's a decorator, so a separate class+method don't need to be defined
# for each function and the class does not need to be instantiated,
# as with Alex Hall's answer
def fact(self, n):
if n > 0:
return n * self(n-1) # doesn't need to be self(self, n-1),
# as with lkraider's answer
else:
return 1
print(fact(10)) # works, as opposed to dursk's answer
Upvotes: 5
Reputation: 4181
You can bind the function to itself, so it receives a reference to itself as first parameter, just like self
in a bound method:
def bind(f):
"""Decorate function `f` to pass a reference to the function
as the first argument"""
return f.__get__(f, type(f))
@bind
def foo(self, x):
"This is a bound function!"
print(self, x)
Source: https://stackoverflow.com/a/5063783/324731
Upvotes: 2
Reputation: 36013
Here's an (untested) idea:
class Foo(object):
def __call__(self, *args):
# do stuff
self(*other_args)
Upvotes: 2