我希望这不是重复的,如果可以的话,我对此表示歉意,但是已经做了一些谷歌搜索,环顾了堆栈溢出,还没有发现任何东西...
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
问题
上述错误中的“比较”指的是什么。我想我要问的是这两种情况之间有什么区别,这会导致两个不同的错误。
答案 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只能对错误消息有帮助。