3

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'
4

1 回答 1

2

这些都是很好的问题!我会尽力一次将它们分解出来:

如何指定一个对象可以发光?

当您在这里说“glom”时,我假设您的意思是“访问”。

Python 具有非常丰富的数据模型,虽然在每种情况下“访问”通常都有一个直观的含义,但猜测起来可能既昂贵又冒险。glom 的方法是提供显式注册 API

如何指定键迭代器?

如果您想将路径(例如'a.b.c'of glom(target, 'a.b.c'))拆分为用于访问该路径的结构化键(和操作),我建议您查看type,特别PathPath.from_text()path.items()

如果您想查看一个对象并确定对象中存在哪些路径,那就更棘手了。

在撰写本文时,glom它仍主要设计用于访问和构建已知结构,并提供一些默认/分支功能。对于所有可能路径的完全无上下文迭代,我目前提供的最好方法是重新映射食谱)。请注意,remap 没有 glom 的插件/注册功能,但它确实可以开箱即用地在常见的 Python 数据类型中迭代 glommable 路径,如本示例所示(相应的glom()调用在下面完成)。

如何指定如何从键中检索数据?

我认为这实际上在我上面引用的注册 API中得到了解决。关键字参数是get指一个内置操作,必须为所有类型指定。

如果您对“检索”的定义与内置get注册冲突,您可以覆盖它,或者您可以指定一个可以针对 using 注册的新操作register_op(例如,如何assign添加操作)。

再一次,很好的问题,你真的在​​这里利用了 Python 的力量。希望这可以帮助!

于 2019-09-03T22:42:29.337 回答