You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 19:06:02