• glom模块使用(二)


    经过咨询库的作者,在最后留的那个问题的准确解法如下:

    import glom
    
    target = {
        'data': {
            'name': 'just_test',
            'likes': [{'ball': 'basketball'},
                      {'ball': 'football'},
                      {'water': 'swim'}]
        }
    }
    
    spec = {
        'name' : ('data.name'),
        'likes' : ('data', 'likes', [glom.Coalesce('ball', 'water')])
    }
    
    print glom.glom(target, spec)
    ####
    {'name': 'just_test', 'likes': ['basketball', 'football', 'swim']}

    非常棒,准确来说就是得灵活运用 Coalesce 方法啊,不能太死板。非常 Pythonic。 另附网址,作者有个很搞笑 little four hair , 哈哈哈哈 Issue 地址

    1. 官方文档地址

    文档地址

    2. 安装方法

    pip install glom

    3. 正式开始

    glom,官方的说法是用 PYTHONIC 的方式来处理内嵌的数据。对于现实世界中的数据处理更加给力,现实世界中的数据,我的理解就是 AJAX 越来越流行了,处理这类数据会越来越频繁。有如下特点:

    • 对于嵌套数据结构的基于路径式的访问
    • 可读,有意义的错误消息
    • 声明性数据转换,使用轻量级,Pythonic 规范
    • 内置数据探索和调试功能

    3.1 原始处理嵌套数据

    下面的脚本包导入

    from glom import glom
     

    下面的 data 就是个简单的嵌套数据,一般都可以用下面几种方法进行处理

    data = {'a': {'b': {'c': 'd'}}}
    data['a']['b']['c']
    data.get('a').get('b').get('c')
    data.get('a', {}).get('b',{}).get('c')
     

    但是当我们的数据改变成下面的这样时:

     
    data2 = {'a': {'b': None}}
    data2['a']['b']['c']
    Traceback (most recent call last):
    ...
    TypeError: 'NoneType' object has no attribute '__getitem__'
     

    会报错,而且由于是嵌套数据,从错误信

    息里我们只知道有个 None 值,但是到底谁是呢,是 a,是 b 呢,反正肯定不是我们的朋友小哪吒。

    3.2 glom 出场

    那么 glom 怎么处理上面的数据呢? 如其所言,路径式:

    data = {'a': {'b': {'c': 'd'}}}
    print glom(data, 'a.b.c')  # d

    看起来还是很优雅, 很 Pythonic。

    data2 = {'a': {'b': None}}
    glom(data2, 'a.b.c')

    错误信息如下:

    glom.core.PathAccessError: could not access 'c', part 2 of Path('a', 'b', 'c'), got error: AttributeError("'NoneType' object has no attribute 'c'",)

    很明显,这个错误就很直观。 难道仅仅只有这个?当然不是

    3.2.1 Going Beyond Access

    上面的是原标题,我的理解是不仅仅获取数据,还有别的呢。 首先,介绍两个基本的术语

    target 目标数据,可以是字典,列表,或其他任意的对象
    spec  我们想要的输出格式 【specifications】, 定义你自己所需要的格式

    现在让我们跟随宇航员的脚步,探索太阳系吧。

    • 获取某个行星的名字:
    target = {'galaxy': {'system': {'planet': 'jupiter'}}}
    # 这个格式就是需要个字段值,所以输出的就是个字段值
    spec = 'galaxy.system.planet'
    glom(target, spec)
    # 'jupyter'
    • 现在,宇航员们想把行星的名字放进一个列表中,数据是这样:
    target = {'system': {'planets': [{'name': 'earth'}, {'name': 'jupiter'}]}}
    • 通常,处理这样的话,都要写个循环,或者搞个列表解析式,那么 glom 怎么处理呢?
    glom(target, ('system.planets', ['name']))
    print glom(target, spec)
    # ['earth', 'jupiter']

    是不是很简单。那么现在新需求又来了,宇航员想得到下面这个数据里面的行星的卫星的数:

    target = {'system': {'planets': [{'name': 'earth', 'moons': 1},
                                      {'name': 'jupiter', 'moons': 69}]}}
    • glom 解决方法:
    # 自定义的格式
    spec = {'names': ('system.planets', ['name']),
            'moons': ('system.planets', ['moons'])}
    print glom(target, spec)
    # {'moons': [1, 69], 'names': ['earth', 'jupiter']}

    3.2.2 Changing Requirements

    Coalesce 是 glom 定义的一种结构,允许我们对于 spec 中的子 spec 进行进一步的处理,你只要在子 spec 中将可能存在的值定义好就行了,听起来有点绕,现在来梳理一下。

    • 首先,子 spec 是什么?
    spec = {'names': ('system.planets', ['name']),
             'moons': ('system.planets', ['moons'])}
    # 以这个为例,这里面的system.planets就是个子spec
    • 然后,使用其解析数据:
    target = {'system': {
        'planets': [{'name': 'earth', 'moons': 1}, {'name': 'jupiter', 'moons': 69}],
    }
    }
    spec = {'names': (Coalesce('system.planets', 'system.dwarf_planets'), ['name']),
             'moons': (Coalesce('system.planets', 'system.dwarf_planets'), ['moons'])}
    
    print glom(target, spec)
    # {'moons': [1, 69], 'names': ['earth', 'jupiter']}
    • 接着当我们的数据变成了这个以后
    target = {'system': {'dwarf_planets': [{'name': 'pluto', 'moons': 5},
                                            {'name': 'ceres', 'moons': 0}]}}
    spec = {'names': (Coalesce('system.planets', 'system.dwarf_planets'), ['name']),
             'moons': (Coalesce('system.planets', 'system.dwarf_planets'), ['moons'])}
    print glom(target, spec)
    # {'moons': [5, 0], 'names': ['pluto', 'ceres']}

       可以看到,依然可以使用相同的 spec 来解析不同的目标数据。 有意思的是,你可以在 target 里面同时写入 plantes 和 dwarf_plants 数据试试看,会返回什么数据。 【这里应该是个惰性的匹配,只要匹配到一个,后面的就不再去匹配了

      简单点说:有时候我们不知道字典中有哪些关键词,这时候可能要一个个的试验。在glom中提供了Coalesce,可以给glom.glom我传入的是多个key,你都给在字典里找找,找到了告诉我结果,所以上面往Coalesce传了多个key,总有一个命中的

    3.2.3 True Python Native

    真正的原生 python 在 glom 里面,你可以传值给 python 里面的任意的函数 举例:

    • 求和
    target = {'system': {'planets': [{'name': 'earth', 'moons': 1},
                                      {'name': 'jupiter', 'moons': 69}]}}
    
    print glom(target, {'moon_count': ('system.planets', ['moons'], sum)})
    
    # {'moon_count': 70}
     

    原教程这里还有个案例,但是我还没有理解好,就不写出来了,大家可以点击链接自己看一下。

    4. 结论

    下一节,为大家带来其中一些重要的函数。 最后,在用的过程中,一直有个疑问,数据如下:

    target = {
        'data': {
            'name': 'just_test',
            'likes': [{'ball': 'basketball'},
                      {'ball': 'football'},
                      {'water': 'swim'}]
        }
    }
     

    现在,我想返回的数据格式为:

    {'name': 'just_for_test', 'likes': ['basketball', 'football', 'water']}

    一开始我以为可以这么用:

    spec = {
        'name': ('data.name'),
        'likes': ('data.likes', ['ball', 'water'] ),
    }

    但是不行,这样会报错。

    转自:https://cuiqingcai.com/6182.html

  • 相关阅读:
    BAPI / RFC with Delphi(系列之一)--安装部件
    如何动态改变Table Control的列抬头
    如何实现标准TCODE的屏幕增强(HOWTO:Implement a screen exit to a standard SAP transaction)
    JNDI 连接Windows Active Directory 教程
    BAPI / RFC with Delphi(系列之三)--TSAPLogonControl使用(无对话框的登录sap的delphi源代码)
    BAPI / RFC with Delphi(系列之二)--TSAPLogonControl使用(有对话框的登录sap的delphi源代码)
    asp.net
    关于ETL的经验总结[经典](转)
    保持Oracle的优良性能
    保持Oracle的优良性能
  • 原文地址:https://www.cnblogs.com/tjp40922/p/14095058.html
Copyright © 2020-2023  润新知