Python继承dict实现自定义缺省返回值 如何避免实例变量入字典
问题解决方案
问题根源
- 第一种方案异常的核心原因是你加了
self.__dict__ = self这行代码:Python实例的普通属性默认存储在实例自带的__dict__特殊字典中,你将它直接指向当前自定义字典实例本身,导致所有给实例设置的属性都会同步变成字典的键值对,所以out会出现在字典输出里。 - 第二种方案使用类变量存储缺省值,类变量是所有实例共享的,修改会全局生效,自然无法满足每个实例独立设置的需求。
可行实现方案
基础版(无需点访问字典键)
直接删掉self.__dict__ = self,用私有实例属性存储独立缺省值即可,实例属性和继承的dict键值对是完全隔离的,不会出现在字典内容中:
class xDict(dict): def __init__(self, *args, default_out=0, **kwargs): super().__init__(*args, **kwargs) # 独立存储每个实例的缺省返回值 self._out = default_out def reap(self, qw): return self[qw] if qw in self else self._out def modify(self, qw): self._out = qw
验证测试
l1 = xDict({'c':2,'x':1}, default_out="NA") l2 = xDict({'r':2, 'd':2}, default_out=0) print(l1) # 输出:{'c': 2, 'x': 1},无额外键 print(l1.reap('none_key')) # 输出:NA print(l2.reap('none_key')) # 输出:0 # 单独修改l1的缺省值 l1.modify(False) print(l1.reap('none_key')) # 输出:False print(l2.reap('none_key')) # 输出:0,不受影响
扩展版(保留用.访问字典键的功能)
如果你之前加self.__dict__ = self是为了支持l.c这种点语法访问字典键,可以重写属性访问的魔法方法实现,同时保持缺省值隔离:
class xDict(dict): def __init__(self, *args, default_out=0, **kwargs): super().__init__(*args, **kwargs) # 调用父类方法存缺省值,避免进入字典 super().__setattr__('_out', default_out) def __getattr__(self, key): # 点访问时优先从字典取值,不存在返回缺省值 return self[key] if key in self else self._out def __setattr__(self, key, value): # 缺省值属性走实例属性存储,其他属性存到字典 if key == '_out': super().__setattr__(key, value) else: self[key] = value def reap(self, qw): return self[qw] if qw in self else self._out def modify(self, qw): self._out = qw
扩展版验证
l = xDict({'c':2,'x':1}) print(l.c) # 输出:2,点访问正常生效 print(l.none_key) # 输出:0,缺省值正常 print(l) # 输出:{'c': 2, 'x': 1},无额外键
内容的提问来源于stack exchange,提问作者user3329732
相关产品推荐
相关产品推荐

