使用pickle.load()触发RecursionError:递归深度超出限制求助
解决pickle.load()时的RecursionError问题
我之前也碰到过类似的问题——pickle保存对象时毫无异常,但加载时突然触发递归深度超出的错误,大概率是对象结构或序列化逻辑里藏着循环引用的坑,给你几个排查和解决的方向:
检查对象的循环引用
pickle理论上支持处理循环引用,但如果你的对象结构特别复杂(比如嵌套层级极深,或者多个对象互相引用形成闭环),就可能触发这个错误。你可以先临时调高Python的递归深度来应急(注意不要调得过大,避免栈溢出):import sys import pickle # 适当调大递归深度,比如设为10000 sys.setrecursionlimit(10000) with open('test_file.pkl', 'rb') as f: obj = pickle.load(f)不过这只是临时方案,最好手动梳理对象之间的引用关系,找到循环引用的源头并解除(比如把双向引用改成弱引用,或者去掉不必要的引用)。
排查自定义类的序列化方法
如果object1是自定义类的实例,检查一下有没有重写__reduce__、__getstate__或__setstate__这些序列化相关的方法——这些方法里如果不小心写了递归逻辑(比如__getstate__返回的字典里包含了对象自身),就会导致加载时无限递归。比如:# 错误示例:__getstate__返回了包含自身的字典 class MyClass: def __init__(self, data): self.data = data def __getstate__(self): return {'self': self, 'data': self.data} # 这里的self会引发循环引用 # 修正后的写法:只返回需要序列化的核心数据 class MyClass: def __init__(self, data): self.data = data def __getstate__(self): return {'data': self.data}尝试使用更低的pickle协议
你用了pickle.HIGHEST_PROTOCOL,虽然高协议效率更高,但某些复杂对象在高协议下的序列化逻辑可能存在bug。试试改用更低版本的协议重新保存对象,再加载:import pickle # 用协议2重新保存(兼容Python2和3) with open('test_file_v2.pkl', 'wb') as a: pickle.dump(object1, a, protocol=2) # 加载新保存的文件 with open('test_file_v2.pkl', 'rb') as f: obj = pickle.load(f)替换pickle为更强大的序列化库
如果以上方法都不行,试试用dill或者cloudpickle——它们是pickle的扩展,能处理更多pickle搞不定的场景,包括更复杂的循环引用、lambda函数、自定义类的特殊结构等:import dill # 用dill保存 with open('test_file.dill', 'wb') as a: dill.dump(object1, a) # 用dill加载 with open('test_file.dill', 'rb') as f: obj = dill.load(f)
内容的提问来源于stack exchange,提问作者Ben Jeffrey
相关产品推荐
相关产品推荐

