我正在构建一些 Python 代码来读取和操作深层嵌套的字典(最终用于与 JSON 服务交互,但是如果用于其他目的会很棒)我正在寻找一种方法来轻松读取/设置/更新深层值字典,不需要很多代码。
@see also Python: Recursively access dict via attributes 以及索引访问? -- Curt Hagenlocher 的“DotDictify”解决方案非常有说服力。我也喜欢 Ben Alman 在 http://benalman.com/projects/jquery-getobject-plugin/ 中为 JavaScript 提供的内容。以某种方式将两者结合起来会很棒。
以 Curt Hagenlocher 和 Ben Alman 的示例为基础,如果 Python 具有以下功能,那就太棒了:
>>> my_obj = DotDictify()
>>> my_obj.a.b.c = {'d':1, 'e':2}
>>> print my_obj
{'a': {'b': {'c': {'d': 1, 'e': 2}}}}
>>> print my_obj.a.b.c.d
1
>>> print my_obj.a.b.c.x
None
>>> print my_obj.a.b.c.d.x
None
>>> print my_obj.a.b.c.d.x.y.z
None
知道这是否可行,如果可行,如何着手修改 DotDictify 解决方案?
或者,可以使 get 方法接受点表示法(并添加一个互补的 set 方法),但是对象表示法肯定更清晰。
>>> my_obj = DotDictify()
>>> my_obj.set('a.b.c', {'d':1, 'e':2})
>>> print my_obj
{'a': {'b': {'c': {'d': 1, 'e': 2}}}}
>>> print my_obj.get('a.b.c.d')
1
>>> print my_obj.get('a.b.c.x')
None
>>> print my_obj.get('a.b.c.d.x')
None
>>> print my_obj.get('a.b.c.d.x.y.z')
None
这种类型的交互对于处理深度嵌套的指令非常有用。有人知道要尝试的另一种策略(或示例代码片段/库)吗?
原文由 Hal 发布,翻译遵循 CC BY-SA 4.0 许可协议
属性树
您的第一个规范的问题是 Python 无法在
__getitem__
中判断,如果在my_obj.a.b.c.d
,您接下来将进一步向下处理一棵不存在的树,在这种情况下,它需要返回一个带有__getitem__
方法的对象,这样你就不会得到AttributeError
抛给你,或者如果你想要一个值,在这种情况下它需要返回None
.我会争辩说,在上述每种情况下,您都应该期望它抛出
KeyError
而不是返回None
。原因是你无法判断None
是指“没有密钥”还是“有人实际存储了None
在那个位置”。对于这种行为,您所要做的就是采用dotdictify
,删除marker
,并将__getitem__
替换为:因为你真正想要的是
dict
和__getattr__
和__setattr__
。可能有一种方法可以完全删除
__getitem__
并说出类似__getattr__ = dict.__getitem__
的内容,但我认为这可能是过度优化,如果您稍后决定需要__getitem__
像这样创建树dotdictify
原来是这样,在这种情况下,您可以将其更改为:我不喜欢原来的
marker
业务dotdictify
。路径支持
The second specification (override
get()
andset()
) is that a normaldict
has aget()
that operates differently from what you describe and doesn甚至没有set
(虽然它有setdefault()
这是get()
的逆运算)。人们期望get
采用两个参数,第二个参数是未找到密钥时的默认值。如果你想扩展
__getitem__
和__setitem__
来处理点分键表示法,你需要修改doctictify
:d2–测试代码: