为何出现RecursionError: pickle对象时超出最大递归深度?
我出于好玩写了个无限循环的代码,结果碰到错误:RecursionError: maximum recursion depth exceeded while pickling an object,错误回溯如下:
Traceback (most recent call last): File "<pyshell#34>", line 2, in <module> exec(p.read()) File "<string>", line 6, in <module> File "<string>", line 6, in <module> File "<string>", line 6, in <module> [Previous line repeated 503 more times] File "<string>", line 4, in <module> RecursionError: maximum recursion depth exceeded while pickling an object
我根本没导入pickle模块,完全搞不懂为啥会出现这个错误。
我在Python解释器里跑了这段代码(提前在文档文件夹里建了空的Cool.py文件,我是Mac用户):
with open("Cool.py", "a")as p1: p1.write("""for _ in range(10): """) p1.write("""with open("Cool.py" "r")as p1: """) p1.write(""" for b in p1: """) p1.write(""" print(b)""")
运行完上面的代码后,我又执行了这段代码来调用Cool.py:
with open("Cool.py") as p: exec(p.read())
我想知道为啥这个错误会和pickle模块扯上关系,优先要原因解释,修复方法倒是其次。
首先明确:这个错误里的pickle和你有没有导入pickle模块完全无关,是Python解释器内部的操作导致的。
1. 你的代码触发了无限递归
你生成的Cool.py代码里有个明显的语法错误:open("Cool.py" "r")缺少逗号,正确写法应为open("Cool.py", "r")。更关键的是,当你用exec(p.read())执行Cool.py时,代码逻辑会陷入无限递归执行的死循环——不管是语法错误触发的异常处理连锁反应,还是反复读取自身代码的逻辑,最终都会让Python的函数调用栈不断加深,超过默认的递归深度限制(默认约1000层)。
2. Python内部用pickle处理错误栈
当递归深度超限,Python需要抛出RecursionError,但为了提供详细的错误回溯信息,解释器会尝试序列化(保存)当前的栈帧状态。这个序列化过程内部使用了pickle模块。
但此时递归深度已经太深,连pickle自身的序列化操作都触发了递归溢出,所以最终的错误信息就变成了maximum recursion depth exceeded while pickling an object——本质还是递归超限,只是错误发生在Python内部处理错误的环节,顺带提到了pickle。
简单总结:你的代码先引发了无限递归,Python在准备报错时用pickle处理栈信息,结果pickle也扛不住这么深的递归,于是错误信息里就带上了pickle的字样,和你自己的代码是否导入pickle完全无关。
内容的提问来源于stack exchange,提问作者Jason Blake

