如何在Python的__new__方法中用pickle实现对象缓存并解决递归报错
问题根因
你代码的递归死循环触发逻辑如下:
- 你自定义的
Cache类在取值时会执行pickle.loads反序列化操作 - 你为
Car类实现了__reduce__方法,指定反序列化时通过Car(name)的方式重建实例 - 调用
Car('audi')时先进入__new__方法查询缓存 → 触发Cache.__getitem__执行反序列化 → 反序列化需要再次调用Car(name)创建实例 → 再次进入__new__查询缓存,形成无限递归,最终抛出递归深度超限错误。
修复方案
方案1:缓存直接存储实例(推荐,适合单进程内缓存场景)
去掉Cache类的序列化逻辑,直接存储原始实例对象,既没有序列化开销,也不会触发反序列化导致的循环调用:
class Cache: def __init__(self): self.d = {} def __setitem__(self, obj, val): self.d[obj] = val def __getitem__(self, obj): return self.d[obj]
方案2:保留序列化能力,修改反序列化构造逻辑
如果你确实需要将缓存内容持久化/跨进程传输,需要保留pickle序列化能力,只要修改__reduce__方法返回的构造函数,让反序列化时跳过__new__的缓存查询逻辑即可:
def __reduce__(self): return (self.__class__.new, (self.name,))
注意事项
如果你后续为Car类新增了__init__方法,需要注意避免__new__返回已有缓存实例时,重复执行__init__覆盖实例属性的问题。
内容的提问来源于stack exchange,提问作者Chang Henry
相关产品推荐
相关产品推荐

