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
相关产品推荐
相关产品推荐

