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

实现带默认值的嵌套字典类时重载[]运算符遇到的赋值失效问题

自定义默认值字典类嵌套修改失效的原因及解决办法

我来帮你分析这个问题,其实核心原因在于你实现的__getitem__方法的逻辑——当访问不存在的键时,你只是返回了默认值的深拷贝,但没有把这个拷贝存入字典的values中。

先看你的原始代码里的关键部分:

def __getitem__(self, key):
    return self.values[key] if key in self.values else deepcopy(self.default)

问题出在哪?

当你使用嵌套的Dict对象时:

  1. 第一次调用d[KEY1],因为KEY1不在d.values里,所以返回一个deepcopy(Dict(42))的临时对象。
  2. 接着你修改这个临时对象的KEY2:d[KEY1][KEY2] = 53——但这个修改只作用在那个临时对象上,并没有把这个临时对象存入d.values。
  3. 当你再次调用d[KEY1]时,KEY1还是不在d.values里,所以又会生成一个全新的deepcopy(Dict(42)),自然看到的还是默认值42。

而普通类型(比如42)没问题,是因为当你执行d[KEY] = 53时,直接调用了__setitem__把值存入了values,后续访问就会取到这个设置的值,不会再触发默认值逻辑。

怎么解决?

只需要修改__getitem__方法,在返回默认值拷贝之前,先把它存入self.values,这样后续的操作就会作用在字典中存储的对象上:

from copy import deepcopy
class Dict:
    def __init__(self, default) -> None:
        self.default = default
        self.values = {}
    def __getitem__(self, key):
        if key not in self.values:
            # 生成默认值拷贝并存入字典
            self.values[key] = deepcopy(self.default)
        return self.values[key]
    def __setitem__(self, key, value):
        self.values[key] = value

现在再测试嵌套场景:

KEY1 = 'k1'
KEY2 = 'k2'
d = Dict(Dict(42))
print(d[KEY1][KEY2]) # 输出42
d[KEY1][KEY2] = 53
print(d[KEY1][KEY2]) # 现在输出53

这次就能得到预期结果了——因为第一次访问d[KEY1]时,生成的Dict(42)拷贝已经被存入d.values,后续修改d[KEY1][KEY2]就是直接修改这个存储在字典里的对象,下次访问自然能看到修改后的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 00:17:42