如何实现仅支持__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
关键逻辑说明
- 临时代理类
TempNested:仅实现__setitem__方法处理链式赋值,其他方法均抛出KeyError,确保直接访问不存在的键时触发错误,而非自动创建子字典。 - 自动类型转换:
__setitem__和__getitem__中都会将普通dict转为NestedDict,保证所有嵌套层级的行为一致。 - 避免递归问题:通过调用父类
super().__getitem__(key)获取已存在的键值,避免了自定义__getitem__方法的递归调用。
内容的提问来源于stack exchange,提问作者awhitin2
相关产品推荐
相关产品推荐

