首页 文章

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

提问于
浏览
8

我希望这不是重复,如果是这样,我道歉,但已经做了一些谷歌搜索并查看堆栈溢出,还没有找到任何东西...

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

The question

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

2 回答

  • 2

    当引发 RecursionError 时,python解释器还可能为您提供导致错误的调用的上下文 . 这仅用于调试,为您提供一个提示,在您的代码中您应该查看哪些内容以解决问题 .

    例如,请参阅此循环 str -call设置,该设置会导致不同的消息:

    >>> 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
    

    在引入 RecursionErrorthe issue discussion上没有此行为的文档,但您可以在cpython代码中搜索Py_EnterRecursiveCall的出现 . 然后,您可以根据引发错误的位置查看将返回的实际上下文:

    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
    
  • 6

    我玩弄了它,发现了一些有趣的结果 .

    据我们所知:

    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知道你正在使用比较器 =,!,<,> 进行比较,并且这个比较永远不会达到'base case'条件(在最大深度的限制范围内) . 所以python让你知道你的比较永远不会收敛到满足条件 .

    当你尝试时,这种乐于助人的感觉开始崩溃

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

    但最终python只能对错误消息有所帮助 .

相关问题