class DotDict(dict): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 递归转换嵌套字典为 DotDict for key, value in self.items(): if isinstance(value, dict) and not isinstance(value, DotDict): self[key] = DotDict(value) def __getattr__(self, key): """属性访问优先级:1. 内置属性 → 2. 键值 → 3. 报错""" try: # 优先返回内置属性(如 keys, items 等方法) return object.__getattribute__(self, key) except AttributeError: if key in self: # 其次返回键值(若存在) return self[key] # 属性不存在时抛出标准异常 raise AttributeError( f"'{type(self).__name__}' object has no attribute '{key}'" ) def __setattr__(self, key, value): """属性设置规则:下划线开头为内置属性,否则为键值""" if key.startswith("_"): # 内置属性直接存储(如 _internal_var) object.__setattr__(self, key, value) else: # 键值处理:自动转换嵌套结构 if isinstance(value, dict) and not isinstance(value, DotDict): value = DotDict(value) self[key] = value # 存储为字典键值 def __delattr__(self, key): """删除逻辑:区分内置属性和键值""" if key.startswith("_"): object.__delattr__(self, key) else: if key in self: del self[key] else: raise AttributeError( f"'{type(self).__name__}' object has no attribute '{key}'" ) # dd = DotDict({"a": {"b": {"c": 1}}}) class CaseInsensitiveDict(dict): def __init__(self, *args, **kwargs): self._key_map = {} super().__init__(*args, **kwargs) # 初始化时处理传入的键 for key in list(self.keys()): self._key_map[key.lower()] = key def __setitem__(self, key, value): key_lower = key.lower() if isinstance(key, str) else key self._key_map[key_lower] = key # 记录原始键 super().__setitem__(key_lower, value) def __getitem__(self, key): key_lower = key.lower() if isinstance(key, str) else key return super().__getitem__(key_lower) def __delitem__(self, key): key_lower = key.lower() if isinstance(key, str) else key del self._key_map[key_lower] super().__delitem__(key_lower) def __contains__(self, key): key_lower = key.lower() if isinstance(key, str) else key return super().__contains__(key_lower) def get(self, key, default=None): key_lower = key.lower() if isinstance(key, str) else key return super().get(key_lower, default) def keys(self): return self._key_map.values() # 返回原始键 def items(self): for key_lower, value in super().items(): yield self._key_map.get(key_lower, key_lower), value