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

重写__hash__方法后无法反序列化pickle对象问题求助

问题分析

反序列化Conflicts对象时触发Link类的__hash__方法报错,核心原因是pickle反序列化的执行顺序导致Link的属性未完全初始化时,就被要求计算哈希值。具体来说:

  • 当反序列化Conflicts对象时,其关联的Link对象可能先被父类或内部结构(如集合)引用,触发__hash__调用,但此时node_a_id/node_b_id还未通过__setstate__完成赋值。
  • Network对象中的Link未触发这种提前哈希的场景,因此序列化正常。
解决方案(不修改Link的__hash__方法)

方案1:给Link类的ID属性设置默认值

在Link类定义时,为node_a_id和node_b_id设置空字符串默认值,确保即使提前触发__hash__,也不会因属性不存在报错,后续__setstate__会覆盖默认值:

class Link:
    node_a: ValueNode = None
    node_a_id : str = ""
    node_b: ValueNode = None
    node_b_id : str = ""

    # 原__init__、__getstate__、__setstate__、__hash__代码保持不变

方案2:控制Conflicts类的反序列化顺序

通过实现Conflicts类的__getstate__和__setstate__,强制先完成Link对象的属性恢复,再处理其他可能触发哈希的结构:

class Conflict:
    # 原__init__代码保持不变

    def __getstate__(self):
        state = self.__dict__.copy()
        # 单独保存Link的状态,用于后续优先恢复
        state["link_state"] = self.link.__getstate__()
        return state

    def __setstate__(self, state):
        # 优先恢复Link的属性
        link_state = state.pop("link_state")
        self.link.__setstate__(link_state)
        # 再恢复Conflict自身的其他属性
        self.__dict__.update(state)
        # 若父类需要处理状态,最后调用父类的__setstate__
        # super().__setstate__(state)

内容的提问来源于stack exchange,提问作者Dayiz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:31:25