RecursionError:比较中超出了最大递归深度

时间:2018-10-18 11:36:40

标签: python python-3.x recursion

我希望这不是重复的,如果可以的话,我对此表示歉意,但是已经做了一些谷歌搜索,环顾了堆栈溢出,还没有发现任何东西...

MCVE

我知道,如果一个函数不断调用自身,那么在没有堆栈溢出的情况下就无法无限期地发生这种情况,因此在达到一定限制后会引发错误。例如:

def foo():
    return foo()

foo()

这会导致以下错误:

RecursionError: maximum recursion depth exceeded

但是,如果我编写如下函数:

def count(n):
    if n == 0:
        return 0
    else:
        return count(n-1)+1

count(1000)

我得到一个略有不同的错误:

RecursionError: maximum recursion depth exceeded in comparison

问题

上述错误中的“比较”指的是什么。我想我要问的是这两种情况之间有什么区别,这会导致两个不同的错误。

2 个答案:

答案 0 :(得分:6)

当引发RecursionError时,python解释器还可以为您提供导致错误的调用的上下文。这仅用于调试,以提示您应该在代码中查找的位置以解决问题。

例如,查看此通函str的呼叫设置,它导致产生不同的消息:

>>> class A:
...     def __str__(self):
...         return str(self.parent)
>>> a = A()
>>> a.parent = a
>>> str(a)
RecursionError: maximum recursion depth exceeded while calling a Python object

在引入RecursionError的{​​{3}}上没有关于此行为的文档,但是您可以在cpython代码中搜索the issue discussion的出现。然后,您将看到将根据发生错误的位置返回的实际上下文:

Py_EnterRecursiveCall(" while encoding a JSON object")
Py_EnterRecursiveCall(" while pickling an object")
Py_EnterRecursiveCall(" in __instancecheck__")
Py_EnterRecursiveCall(" in __subclasscheck__")
Py_EnterRecursiveCall(" in comparison")
Py_EnterRecursiveCall(" while getting the repr of an object")
Py_EnterRecursiveCall(" while getting the str of an object")
Py_EnterRecursiveCall(" while calling a Python object")
Py_EnterRecursiveCall("while processing _as_parameter_") # sic
# .. and some more that I might have missed

答案 1 :(得分:2)

我玩了一下,发现了一些有趣的结果。

我们知道:

def foo():
    foo()

礼物升起

RecursionError: maximum recursion depth exceeded

我发现的是

def bar():
    if False:
        return 0
    else:
        bar()

def baz():
    if True:
        baz()
    else:
        return 0

bar()baz()都产生

RecursionError: maximum recursion depth exceeded

然后

def ding():
    if 1 == 2:
        return 0
    else:
        ding()

def dong():
    if 1 != 2:
        dong()
    else:
        return 0

ding()dong()都产生

RecursionError: maximum recursion depth exceeded in comparison

我的直觉是python知道您正在使用比较器=,!,<,>进行比较,并且该比较从未达到“基本情况”条件(在最大深度的范围内)。因此python让您知道您的比较永远不会收敛以满足条件。

尝试时,这种帮助开始失效

def oops():
    if 1 == 2:
        oops()
    else:
        oops()

但是最终,python只能对错误消息有帮助。