python 方法可以无限期地调用自身吗

Is it OK for a python method to call itself indefinitely

我有一个 python 方法,它不时执行一些任务。 我发现最简单的方法是写:

class MyClass:
    def a(self):
        #perform the task 
        time.sleep(time_to_sleep)
        self.a()

但是该方法应该 运行 很长一段时间,可能几个月,这意味着它最多可以递归调用 10^4 次。

这样做有什么风险吗?

如果你无限期地递归到你的函数中,迟早你会得到以下错误 -

RuntimeError: maximum recursion depth exceeded

一个简单的例子来说明这一点 -

>>> def a():
...     global i
...     i += 1
...     a()

然后我运行这个函数使用as -

>>> i = 0
>>> a()

这给了我上面的错误,然后当我打印 i 的值时它是 999。所以迟早你会得到那个错误。

你也可以通过调用 sys.setrecursionlimit() 来改变这个限制,虽然我不建议这样做,因为你可能会在你达到限制之前结束堆栈(更简单的方法是使用while 循环如下面的答案)-

import sys
sys.setrecursionlimit(<limit>)

或者您还可以获得 - MemoryError - 如果您在本地命名空间中存储大量数据,因为您从未真正从递归调用中返回,调用函数的本地命名空间永远不会被清除。所以你甚至可以在你达到最大递归限制之前结束你的内存。


您尝试做的简单方法是使用 while 循环,例如 -

class MyClass:
    def a(self):
        while True:
            #perform the task 
            time.sleep(time_to_sleep)

简而言之:不!
递归函数有调用限制。作为证明,您可以看到自己正在修改 sys.setrecursionlimit:

import time, sys
# max calls: 3
sys.setrecursionlimit(3)

class MyClass:
    def a(self):        
        print "."
        time.sleep(1)
        self.a()

m = MyClass()
m.a()

当调用次数达到 3 时,您会看到: 运行时错误:

.
.
Traceback (most recent call last):
  File "teste.py", line 14, in <module>
    m.a()
  File "teste.py", line 11, in a
    self.a()
  File "teste.py", line 11, in a
    self.a()
RuntimeError: maximum recursion depth exceeded

仅供参考,您可以获得这样的递归限制:

>>> import sys
>>> sys.getrecursionlimit()

Also, be aware: Setting a too high value and over the sys.getrecursionlimit(), you may cause an overflow of the C stack, making the Python interpreter fails.