RecursionError是CPython为防止C栈溢出而设的安全熔断机制,非代码错误;每次递归调用均在有限C栈中新增栈帧,存参数、变量等,超默认约1000层即抛异常。

Python 报 RecursionError: maximum recursion depth exceeded 不是因为代码写错了,而是解释器主动踩了刹车——它用 C 栈管理每次函数调用,而栈空间是操作系统级的有限资源。
递归调用在底层是怎么堆积栈帧的
每次函数调用(包括递归)都会在 C 栈上分配一个栈帧,存参数、局部变量、返回地址等。Python 默认只允许约 1000 层嵌套,不是算力不够,是为防栈溢出导致整个解释器崩溃(比如 Segmentation fault)。你看到的报错,其实是 CPython 在栈快满前就抛出异常,属于安全熔断机制。
@property 或 __getattr__ 里不小心 self.xxx 就会无限递归
这类错误不依赖数据规模,一行代码就能触发:
-
@property的 getter 里写return self.id→ 再次触发同一 getter,无终止 -
__getattr__中访问self.x而 x 不存在 → 又进__getattr__,死循环 - 装饰器、日志钩子、ORM 字段访问等隐式调用,也可能悄悄加长调用链
为什么 sys.setrecursionlimit() 容易让程序更不稳定
调高限制只是把“刹车点”往后挪,并没扩大实际可用栈空间:
立即学习“Python免费学习笔记(深入)”;
- Linux/macOS 下线程默认栈大小约 8MB,按每层 ~1.5KB 算,撑死也就 5000 层左右;设成
10000很可能直接段错误 - Windows 栈更小(通常 1MB),风险更高
- 该设置是全局的,第三方库或并发线程都受其影响
- 没法跨平台预测安全值,生产环境禁止无实测硬设
真正该检查的三件事
遇到这个报错,别急着改 limit,先确认:
- 递归终止条件是否覆盖所有路径?比如
if n < 0漏判,负数输入就失控 - 每次递归参数是否真在收敛?
n-1OK,n-0.5或未变的n就卡住 - 是不是本可以用迭代替代?树遍历、JSON 扁平化、文件夹扫描,90% 场景用
list当栈更稳
最常被忽略的是:报错时的调用栈里混进了你没意识到的间接调用——比如重载了 __eq__,又在里面用了 == 比较自身,就多埋了一层递归入口。


















