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

如何实现仅支持__setitem__的Python嵌套字典?__getitem__抛KeyError

实现支持赋值自动嵌套、访问不存在键抛KeyError的嵌套字典

核心实现思路

继承原生dict类,通过重写__getitem__和__setitem__方法,区分赋值场景和普通访问场景:

  • 访问不存在的键时,返回仅支持赋值的临时代理对象,其他操作直接抛出KeyError
  • 赋值时自动处理嵌套层级创建,同时将普通dict自动转换为自定义嵌套字典类型,保证行为一致性

完整代码实现

class NestedDict(dict):
    def __getitem__(self, key):
        if key not in self:
            # 临时代理类,仅支持赋值操作
            class TempNested:
                def __setitem__(self, nested_key, value):
                    # 创建当前层级的NestedDict并完成赋值
                    self[key] = NestedDict()
                    self[key][nested_key] = value
                
                # 拦截所有非赋值操作,抛出KeyError
                def __getitem__(self, nested_key):
                    raise KeyError(nested_key)
                
                def __repr__(self):
                    raise KeyError(key)
                
                def __getattr__(self, attr):
                    raise KeyError(key)
            
            return TempNested()
        
        # 若键存在,确保值为NestedDict类型(自动转换普通dict)
        value = super().__getitem__(key)
        if isinstance(value, dict) and not isinstance(value, NestedDict):
            self[key] = NestedDict(value)
            return self[key]
        return value
    
    def __setitem__(self, key, value):
        # 自动将赋值的普通dict转为NestedDict
        if isinstance(value, dict) and not isinstance(value, NestedDict):
            value = NestedDict(value)
        super().__setitem__(key, value)

使用示例

# 初始化嵌套字典
nd = NestedDict()

# 链式赋值自动创建中间层级
nd['level1']['level2']['level3'] = 100
print(nd['level1']['level2']['level3'])  # 输出: 100

# 直接访问不存在的键抛出KeyError
try:
    print(nd['nonexist'])
except KeyError as e:
    print(f"捕获KeyError: {e}")  # 输出: 捕获KeyError: 'nonexist'

# 赋值普通dict自动转换为NestedDict
nd['data'] = {'name': 'Alice', 'age': 25}
print(nd['data']['name'])  # 输出: Alice

# 手动创建嵌套层级
nd['manual'] = NestedDict()
nd['manual']['sub'] = 'test'
print(nd['manual']['sub'])  # 输出: test

关键逻辑说明

  1. 临时代理类TempNested:仅实现__setitem__方法处理链式赋值,其他方法均抛出KeyError,确保直接访问不存在的键时触发错误,而非自动创建子字典。
  2. 自动类型转换:__setitem__和__getitem__中都会将普通dict转为NestedDict,保证所有嵌套层级的行为一致。
  3. 避免递归问题:通过调用父类super().__getitem__(key)获取已存在的键值,避免了自定义__getitem__方法的递归调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:17:38