Glom(https://glom.readthedocs.io/en/latest/)除其他外,用于
嵌套结构的基于路径的访问
但是你如何使它适用于字典之外的嵌套结构呢?
考虑以下类(为简单起见,故意不是实际collection.abc.Mapping
的:
class MyMap:
def __init__(self, d):
self.d = d
def __getitem__(self, k):
"""just delegating"""
v = self.d[k]
if isinstance(v, (dict, MyMap)):
return MyMap(v)
else:
return v
这有效:
m = MyMap({'a': {'b': {'c': 'd'}}})
assert m['a']['b']['c'] == 'd'
但这不会:
from glom import glom
assert glom(m, 'a.b.c') == 'd'
我得到错误:
PathAccessError: could not access 'a', part 0 of Path('a', 'b', 'c'), got error: AttributeError("'MyMap' object has no attribute 'a'")
更具体地说,如何指定:
- 什么是节点(即可以进一步修饰的对象)
- 键迭代器(如何将路径拆分为键)
- item getter(如何从键中检索数据)
如果它有帮助,这是我正在寻找 glom 来满足的那种功能:
dot_str_key_iterator = lambda p: p.split('.')
bracket_getter = lambda obj, k: obj[k]
def simple_glom(target, spec,
node_types=(dict,),
key_iterator=dot_str_key_iterator,
item_getter=bracket_getter
):
for k in key_iterator(spec):
target = item_getter(target, k)
if not isinstance(target, node_types):
break
return target
这个功能没有所有的花里胡哨,但允许我做:
m = MyMap({'a': {'b': {'c': 'd'}}})
simple_glom(m, 'a.b.c', node_types=(MyMap,))
或者对于使用所有参数的极端示例:
from types import FunctionType
from functools import partial
attr_glom = partial(simple_glom,
node_types=(FunctionType, type),
key_iterator=lambda p: p.split('/'),
item_getter=getattr)
assert attr_glom(MyMap, '__getitem__/__doc__') == 'just delegating'