Python使用递归时栈溢出的解决方案

最近没事测试谢了个拉取FTP文件的脚本,其中一段是要检测FTP文件的中间状态,所谓中间状态就是FTP的文件正在上传,并还没有传完的这个时段的状态,我写了一个简单脚本测试

def check_filesize(filename):
    file_size = ftp_operation.RemoteFileSize(config['remote_dir'], filename)
    time.sleep(1)
    file_size2 = ftp_operation.RemoteFileSize(config['remote_dir'], filename)
    if file_size2 != file_size:
        check_filesize(filename)

通过sleep几秒钟分别两次获取FTP文件的大小进行比较,如果不一样大小就调用函数本身(递归),然后才发现递归次数较多会发生栈溢出的问题,大概跑了800多次吧。

然后百度了下,找到一些可参考的博客和详解,如下

在Python中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,相当于一次push压栈操作,每当函数返回,相当于一次pop出栈操作。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

Windows程序的内存机制大概是这样的,全局变量(局部的静态变量本质也属于此范围)存储于堆内存,该段内存较大,一般不会溢出;函数地址、函数参数、局部变量等信息存储于栈内存,栈内存较小容易发生溢出现象,但是效率高。

栈溢出的可能原因:
1. 函数递归调用层次过深 ,每调用一次,函数的参数、局部变量等信息就压一次栈,并且没有及时出栈。
2. 局部变量体积太大

解决方案:
1.把递归调用函数改用while或者for循环来实现 。
2.通过尾递归优化。
3.改用堆内存,函数里定义很大的局部变量(例如大数组),这种情况可以将局部变量改为静态变量(实质上也是全局变量)。
4.增大栈的大小值。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://sulao.cn/post/645.html