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?
-
Possible duplicate of Can a lambda function call itself recursively in Python?metatoaster– metatoaster2015-10-19 02:17:04 +00:00Commented Oct 19, 2015 at 2:17
-
why do you need to change the name of the function? You can do it but a lot of the time there is a better method than a dynamic function name.LinkBerest - SO sold our work– LinkBerest - SO sold our work2015-10-19 02:18:37 +00:00Commented Oct 19, 2015 at 2:18
-
This is an interesting thought but I hope that in reality you're using a decent IDE or other tool to refactor safely rather than weird tricks like this.Alex Hall– Alex Hall2015-10-19 02:21:58 +00:00Commented Oct 19, 2015 at 2:21
-
in reality i'm playing with python over SSH and i'm using vimuser4259083– user42590832015-10-19 02:30:12 +00:00Commented Oct 19, 2015 at 2:30
-
3As a fan of long and descriptive function names it always annoyed me to repeat them inside themselves if the functions are recursive. It violates the DRY-principle. I think this problem should be addressed on code level an not be delegated to the IDE. It also makes can also make codesnippets more readable as the recursive character becomes obvious directly (one does not need to remember the function name).cknoll– cknoll2018-06-07 08:02:11 +00:00Commented Jun 7, 2018 at 8:02
Add a comment
|
5 Answers
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
Comments
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)
Comments
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):
...