Python—函数可以在不显式使用名称的情况下调用自身吗?

Python—函数可以在不显式使用名称的情况下调用自身吗?,python,recursion,refactoring,inspection,Python,Recursion,Refactoring,Inspection,或者一个更广泛的问题:如何在python中创建递归函数,并且在更改其名称时,只需在声明中更改它?这里有一个(未经测试的)想法: 我不知道你为什么要这样做,但尽管如此,你可以使用一个工具来实现这一点 def recursive_function(func): def decorator(*args, **kwargs): return func(*args, my_func=func, **kwargs): return decorator 然后你的函数看起来像:

或者一个更广泛的问题:如何在python中创建递归函数,并且在更改其名称时,只需在声明中更改它?

这里有一个(未经测试的)想法:


我不知道你为什么要这样做,但尽管如此,你可以使用一个工具来实现这一点

def recursive_function(func):
    def decorator(*args, **kwargs):
        return func(*args, my_func=func, **kwargs):
    return decorator
然后你的函数看起来像:

@recursive_function
def my_recursive_function(my_func=None):
    ...

您可以将函数绑定到自身,这样它将收到对自身的引用作为第一个参数,就像绑定方法中的
self

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)

来源:

我找到了一个简单有效的解决方案

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

免责声明:肮脏的解决方案,但不需要装饰师

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
导入系统 def阶乘(x): _f=eval(sys.\u getframe().f\u code.co\u name) 如果x>>阶乘(5),则返回x 120
为什么需要更改函数名称的可能重复项?你可以这样做,但很多时候有一种比动态函数名更好的方法。这是一个有趣的想法,但我希望实际上你正在使用一个体面的IDE或其他工具来安全地重构,而不是像这样奇怪的把戏。事实上,我在玩python over SSH,我使用vimAs作为长函数和描述性函数的粉丝如果函数是递归的,那么在它们内部重复它们总是让我恼火。这违反了干燥原则。我认为这个问题应该在代码级别解决,而不是委托给IDE。它还可以使代码片段更具可读性,因为递归字符直接变得明显(不需要记住函数名)。
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