Python中递归深度究竟指什么?为何调用f(1)触发RecursionError?
Python递归深度的误解与实际定义
我原本以为Python执行递归函数时,内部会创建存储函数调用的栈,递归深度就是栈中函数调用的数量,但实际情况并非如此。
比如下面这个阶乘递归函数:
def f(n): if (n == 1): return 1 else: return n*f(n-1)
按照之前的理解,调用f(1)时,应该直接触发if条件返回1,不会有递归嵌套。但当我用以下代码把最大递归深度设为3后:
import sys sys.setrecursionlimit(3)
调用f(1)居然触发了RecursionError:
RecursionError: maximum recursion depth exceeded while calling a Python object
这就很奇怪——此时栈里应该只有一个f(1)的调用,返回后就会弹出,为什么会触发深度超限?Python里的递归深度到底指的是什么?
为什么f(1)会触发递归深度错误?
Python的递归深度限制不是只统计当前递归函数的调用栈数量,而是统计整个Python解释器的调用栈总深度——包括主程序的调用、模块加载的相关调用,甚至是解释器自身初始化的一些调用。
当你设置sys.setrecursionlimit(3)时,这个值是整个调用栈的最大允许深度,而非你写的递归函数的嵌套层数。比如,当你在脚本里执行f(1)时,调用栈的深度已经包含了:
- 脚本主程序的入口调用栈帧
f(1)自身的调用栈帧
再加上解释器启动时的基础栈帧,总深度已经超过了你设置的3,所以直接触发了RecursionError。
Python递归深度的实际定义
Python官方定义的递归深度,是指当前Python解释器的调用栈的总层数,从解释器启动后的初始栈帧开始,到当前正在执行的函数栈帧为止的总数量。
这个限制的本质是为了防止无限递归导致解释器栈溢出崩溃,它统计的是全局的调用栈深度,而非单个递归函数的嵌套调用次数。比如默认的递归深度限制是1000,这个数值包含了所有前置调用栈,你的递归函数嵌套次数最多只能占到其中的一部分,而非刚好1000次。
内容的提问来源于stack exchange,提问作者Rajdeep Sindhu
相关产品推荐
相关产品推荐

