python 堆栈溢出_关于递归:致命的Python错误:无法从堆栈溢出中恢复

我在互联网上读过类似的问题,但是没有答案可以帮助我。我有一个函数,对于每一行数据(数据大约有2'000'000行)执行某项操作,然后根据执行的操作使用不同的参数来调用相同的函数。问题是一段时间后,我在终端中收到以下错误:"致命的Python错误:无法从堆栈溢出中恢复"。

它似乎是导致此错误的最常见错误是无限循环,但我控制且没有无限循环。因此,对我来说,'sys.getrecursionlimit()'设置为3000,这意味着在调用同一函数3000之后,它将给我错误。

第一件事是,我不了解"致命的Python错误:无法从堆栈溢出中恢复"之间的区别。在终端中,或者在jupyternotebook中出现" RecursionError:在比较中超出了最大递归深度"。确实,对我来说,它可能来自相同的错误(例如无限循环)。

当用一个简单的名为" test_"的函数替换我的函数时,我有以下代码:

import sys

print(sys.getrecursionlimit())

def test_(x,t):

x = x+1

if x

test_(x=x,t=t)

print(test_(0,2971)) # output: None

print(test_(0,2972)) # RecursionError: maximum recursion depth exceeded in comparison

3000

None

--------------------------------------------------------------------------- RecursionError Traceback (most recent call

last) in ()

8

9 print(test_(0,2971))

---> 10 print(test_(0,2972))

in test_(x, t)

5 x = x+1

6 if x 7 test_(x=x,t=t)

8

9 print(test_(0,2971))

... last 1 frames repeated, from the frame below ...

in test_(x, t)

5 x = x+1

6 if x 7 test_(x=x,t=t)

8

9 print(test_(0,2971))

RecursionError: maximum recursion depth exceeded in comparison

为了解决这个问题,我在不损失"运行连续性"的情况下调整了功能,以便可以批量使用:

for i in np.arange(0,9000,2000):

test_(i,i+2000)

会有更好的解决方案吗?同样,当我们知道我们有很多迭代要做时,通常做一个递归函数是一个坏主意?也有人知道我如何在每个循环中打印递归深度吗?

我正在使用jupyter笔记本在Linux虚拟环境中使用anaconda在python 3.6上进行开发。

您是否可以从函数返回当前状态,然后让调用方再次调用它? 然后,您就不会耗尽堆栈。

@miki,我用批处理方法测试了您的代码,它对我有用。 也许在运行for循环的地方递归限制不同?

谢谢您的回答,乔纳森。 我将尝试这种方法,但是我们确定错误是由于多次嵌入函数而导致的? 因为,如果是这样的话,那么批次校正应该已经纠正了错误,不是吗?

谢谢@Elad! 是的,它也对我有用,但是在我的真实函数(而不是该测试一个)的情况下,我一直在收到错误信息...因此,为什么我想在每次迭代中打印递归深度以更好地理解它。

请检查此问题(对我有用):

如何获得Python解释器堆栈的当前深度?

您基于该答案的代码:

import sys

import inspect

print(sys.getrecursionlimit())

def test_(x,t):

print len(inspect.stack())

x = x+1

if x

test_(x=x,t=t)

print(test_(0,7))

输出:

22

23

24

25

26

27

28

None

非常感谢@Elad的帮助。因此,我可以解决我的问题!现在,我将使用它来了解主要问题,并在解决主要问题时通知您。另外,出于好奇,这是一件小事,我不明白为什么在这个数字不能达到3000之前他们是错误的...您有什么主意吗?

相同的inspect模块还可以帮助您理解,只需" print inspect.stack()",您就会看到python在开始执行代码之前先执行了一些功能。

这似乎可以解释为什么它从21开始,但是对我来说,它不能解释为什么它不能达到3000 ...也许我错过了什么?您还知道为什么有时会在笔记本中打印出相同的错误:RecursionError:相比较而言,最??大递归深度超出了,有时在终端中出现了致命的Python错误:无法从堆栈溢出中恢复。那也将有很大帮助。非常感谢您的所有回答!

@miki,我相信异常发生时确实会达到3000,在您的测试中x从0开始而不是当前递归长度(这在很大程度上取决于您运行脚本的位置),另一个问题是,当捕获异常时,它已经回溯了一些堆栈,所以您不会看到3000个仅接近它的数字。关于您描述的第二个问题,我无能为力。

如果将以下行添加到函数test_中:else:print(len(inspect.stack())),然后运行test_(0,2962),它将完成并打印2983,而如果您运行test_(0,2963) ,它将给出RecursionError。因此,它不是在3000或2963而不是2983结束(即我猜我从0开始的事实与之无关)。但这可能是由于您的第二种解释:)。感谢你所做的一切!

我的问题是在连接不良时向一些API发送请求。 这是一个使用bot.polling()方法的库,因此请求可能溢出或其他原因。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值