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

Python不可变State类的next方法如何返回新实例不修改原对象

State类不可变next方法修复方案

问题根因

你当前实现的核心问题是:

  • dataclasses.replace对state字段执行的是浅拷贝,新生成的tempState和原实例共享同一个字典对象,并未生成独立的新字典
  • 直接修改tempState.state[k]本质是修改这个共享字典的内容,会同步改动原实例的状态,完全违背了不可变状态的设计要求
  • 额外注意:你的原实现未导入dataclasses.replace,直接运行会抛出名称错误,且原有__hash__方法仅对字典的键做哈希,值变更时哈希值不会更新,逻辑有误

修复方案

直接基于原有状态字典生成新的独立字典,再实例化新的State对象即可,无需使用dataclasses.replace,完整修正代码如下:

from __future__ import annotations
from typing import Any
from dataclasses import dataclass

@dataclass(frozen=True, order=True, init=False)
class State:
    state: dict[str, Any]

    def __init__(self, **kwargs) -> None:
        object.__setattr__(self, "state", kwargs)

    def next(self, **kwargs) -> State:
        # 生成全新的状态字典:先复制原有所有键值,再用传入参数覆盖更新
        updated_state = {**self.state, **kwargs}
        return State(**updated_state)

    def __hash__(self) -> int:
        # 同时对键和值做哈希,确保状态变更时哈希值同步更新
        return hash(tuple(sorted(self.state.items())))

验证说明

你提供的测试用例中assert s1 != s2本身天然成立(s1的v1初始为False,s2的v1初始为True),符合预期的完整测试逻辑应该补充验证新状态正确性、原状态不被修改:

def test_next_state_immutable():
    s1 = State(v1 = False, v2 = True, v3 = "open")
    s2 = State(v1 = True, v2 = True, v3 = "open")
    # 生成新状态
    res = s1.next(v1 = True)
    # 验证原状态未被修改
    assert s1.state["v1"] is False
    # 验证新状态符合预期
    assert res == s2

内容的提问来源于stack exchange,提问作者Albin Ekström

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:15:00