如何使 glom 与类似 dict 的对象一起工作
How to make glom work with dict-like objects
Glom (https://glom.readthedocs.io/en/latest/) 除其他外,还用于
path-based access for nested structures
但是如何让它适用于字典以外的嵌套结构?
考虑以下 class(为简单起见,故意不是实际的 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'")
更具体,如何指定:
- 什么是节点(即可以进一步 glommed 的对象)
- 一个键迭代器(如何将路径拆分为键)
- 一个项目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'
这些都是很好的问题!我会尽力一次把它们分解出来:
如何指定对象可以 glommed?
当你在这里说 "glom" 时,我假设你的意思是 "access"。
Python 具有非常丰富的数据模型,虽然 通常 在任何情况下 "access" 都有直观的含义,但它可能代价高昂且存在风险猜测。 glom 对此的处理方法是 provide explicit registration APIs.
如何指定一个键迭代器?
如果您想将 路径(例如,glom(target, 'a.b.c')
的 'a.b.c'
)拆分为用于访问该路径的结构化键(和操作)路径,我建议查看 the Path
type,特别是 Path.from_text()
和 path.items()
.
如果您想查看一个对象并确定该对象中存在哪些路径,那就比较棘手了。
在撰写本文时,glom
仍主要用于访问和构建已知结构,并为 defaults/branching 提供一些功能。对于所有可能路径的完整上下文无关迭代,我目前必须提供的最好的是 remap (cookbook). Note that remap doesn't have glom's plugin/registration power, but it does work out-of-the-box for iterating glommable paths in common Python datatypes, as this example 显示(相应的 glom()
调用在下面完成)。
如何指定如何从键中检索数据?
我认为这实际上在我上面提到的 the registration APIs 中得到了解决。 get
关键字参数指的是一个内置操作,必须为所有类型指定。
如果您对 "retrieve" 的定义与内置 get
注册冲突,您可以覆盖它, 或 您可以指定一个添加了可以使用 register_op
, (e.g., how the assign
操作注册的新操作。
再一次,很好的问题,你真的在这里利用了 Python 的力量。希望这对您有所帮助!
Glom (https://glom.readthedocs.io/en/latest/) 除其他外,还用于
path-based access for nested structures
但是如何让它适用于字典以外的嵌套结构?
考虑以下 class(为简单起见,故意不是实际的 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'")
更具体,如何指定:
- 什么是节点(即可以进一步 glommed 的对象)
- 一个键迭代器(如何将路径拆分为键)
- 一个项目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'
这些都是很好的问题!我会尽力一次把它们分解出来:
如何指定对象可以 glommed?
当你在这里说 "glom" 时,我假设你的意思是 "access"。
Python 具有非常丰富的数据模型,虽然 通常 在任何情况下 "access" 都有直观的含义,但它可能代价高昂且存在风险猜测。 glom 对此的处理方法是 provide explicit registration APIs.
如何指定一个键迭代器?
如果您想将 路径(例如,glom(target, 'a.b.c')
的 'a.b.c'
)拆分为用于访问该路径的结构化键(和操作)路径,我建议查看 the Path
type,特别是 Path.from_text()
和 path.items()
.
如果您想查看一个对象并确定该对象中存在哪些路径,那就比较棘手了。
在撰写本文时,glom
仍主要用于访问和构建已知结构,并为 defaults/branching 提供一些功能。对于所有可能路径的完整上下文无关迭代,我目前必须提供的最好的是 remap (cookbook). Note that remap doesn't have glom's plugin/registration power, but it does work out-of-the-box for iterating glommable paths in common Python datatypes, as this example 显示(相应的 glom()
调用在下面完成)。
如何指定如何从键中检索数据?
我认为这实际上在我上面提到的 the registration APIs 中得到了解决。 get
关键字参数指的是一个内置操作,必须为所有类型指定。
如果您对 "retrieve" 的定义与内置 get
注册冲突,您可以覆盖它, 或 您可以指定一个添加了可以使用 register_op
, (e.g., how the assign
操作注册的新操作。
再一次,很好的问题,你真的在这里利用了 Python 的力量。希望这对您有所帮助!