我发现访问字典键更方便 obj.foo
而不是 obj['foo']
,所以我写了这个片段:
class AttributeDict(dict):
def __getattr__(self, attr):
return self[attr]
def __setattr__(self, attr, value):
self[attr] = value
但是,我认为 Python 没有提供开箱即用的功能肯定是有原因的。以这种方式访问 dict 键的注意事项和陷阱是什么?
原文由 Izz ad-Din Ruhulessin 发布,翻译遵循 CC BY-SA 4.0 许可协议
更新 - 2020
自从大约十年前提出这个问题以来,从那时起 Python 本身就发生了相当多的变化。
虽然我原来的答案中的方法在某些情况下仍然有效(例如遗留项目坚持使用旧版本的 Python 以及您确实需要使用非常动态的字符串键处理字典的情况),但我认为通常 Python 中引入的 数据类 3.7 是
AttrDict
绝大多数用例的明显/正确解决方案。原答案
最好的方法是:
一些优点:
.keys()
工作得很好。除非 - 当然 - 你为它们分配了一些值,见下文)AttributeError
而不是KeyError
缺点:
.keys()
这样的方法如果被传入数据覆盖将 无法 正常工作E1123(unexpected-keyword-arg)
和E1103(maybe-no-member)
这是如何工作的简短解释
__dict__
的字典中。__dict__
需要“只是一个普通的字典”,所以我们可以将dict()
的任何子类分配给内部字典。AttrDict()
实例(就像我们在__init__
中一样)。super()
的__init__()
方法,我们确保它(已经)的行为与字典完全一样,因为该函数调用所有 字典实例化 代码。Python 不提供开箱即用的此功能的一个原因
如“缺点”列表中所述,这将存储键的命名空间(可能来自任意和/或不受信任的数据!)与内置 dict 方法属性的命名空间结合在一起。例如: