为了账号安全,请及时绑定邮箱和手机立即绑定

glom初级教程

标签:
Python

1.glom介绍

通常对于字典和json的提取我们都是使用如下方式

>>> data = {'a': {'b': {'c': 'd'}}}>>> data['a']['b']['c']'d'

这种方式看起来简单,但是如果字段结构改变就引发了悲剧

>>> data2 = {'a': {'b': None}}>>> data2['a']['b']['c']
Traceback (most recent call last):...
TypeError: 'NoneType' object is not subscriptable

错误虽然出来,可是没有直观告诉我们是哪个key引起的,a、b、c? 

这个时候glom就应运而生,它非常方便的解决字典或者json嵌套的取值,还提供了输出控制,格式控制,结构容错等功能。

开始之前先对glom用法做一个介绍,它包含一下两个术语

  1. target: 需要提取的dict、json、list或者其他对象。

  2. spec: 我们想要的输出

output = glom(traget, spec) 这样就会提交到内存,然后得到我们想要的格式

>>> target = {'galaxy': {'system': {'planet': 'jupiter'}}}>>> spec = 'galaxy.system.planet'>>> glom(target, spec)'jupiter'

2.glom安装

pip install glomfrom glom import *

3.基本路径提取

glom提供了三种路径提取的方式

  1. 字符串

  2. Path对象

字符串

路径直接提取数据 (单路单一匹配)

>>> target = {'galaxy': {'system': {'planet': 'jupiter'}}}>>> spec = 'galaxy.system.planet'>>> glom(target, spec)'jupiter'

现在数据结构换了,planet变成list了

>>> target = {'system': {'planets': [{'name': 'earth'}, {'name': 'jupiter'}]}}>>> glom(target, ('system.planets', ['name']))
['earth', 'jupiter']

现在要求变了,数据加字段了,output需要多个字段 (多路径单一匹配)

复制代码

>>> target = {'system': {'planets': [{'name': 'earth', 'moons': 1}, {'name': 'jupiter', 'moons': 69}]}}>>> spec1 =('system.planets', ['name'])>>> spec2 =  ('system.planets', ['moons'])}>>> pprint(glom(target, spec1))
['earth', 'jupiter']>>> pprint(glom(target, spec2))
[1, 69]

复制代码

这样写太麻烦了,glom提供了一个合并的方法,使用字典的方式格式化输出

>>> target = {'system': {'planets': [{'name': 'earth', 'moons': 1},{'name': 'jupiter', 'moons': 69}]}>>> spec = {'names': ('system.planets', ['name']), 'moons': ('system.planets', ['moons'])}>>> pprint(glom(target, spec))
{'moons': [1, 69], 'names': ['earth', 'jupiter']}

现在更复杂了,不仅多了字段,有的数据key也发生了变化 (多路径多匹配)

复制代码

>>> target1 = {'system': {'dwarf_planets': [{'name': 'pluto', 'moons': 5},... {'name': 'ceres', 'moons': 0}]}}>>> target2 = {'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'])}>>> pprint(glom(target, spec))
{'moons': [1, 69], 'names': ['earth', 'jupiter']}

复制代码

Path对象

比如路径包含int,datetime等不适合使用'a.b.c'这种方式调用的,需要使用Path

>>> target = {'a': {'b': 'c', 'd.e': 'f', 2: 3}}>>> glom(target, Path('a', 2))3
>>> glom(target, Path('a', 'd.e'))'f'

Path支持join

>>> Path(T['a'], T['b'])T['a']['b']>>> Path(Path('a', 'b'),Path('c', 'd'))
Path('a', 'b', 'c', 'd')

Path支持切片

>>> path = Path('a', 'b', 1, 2)>>> path[0]
Path('a')>>> path[-2:]
Path(1, 2)

具体用法就是将字符串路径我位置替换成相应的Path对象

T

面向对象的表达方式,但是目前只能提取数据,不能做加工

>>> spec = T['a']['b']['c']>>> target = {'a': {'b': {'c': 'd'}}}>>> glom(target, spec)'d'

T提取出来的就是对应的python对象,(具体用法待考证)

复制代码

>>> from glom import T>>> target = {'system': {'planets': [{'name': 'earth', 'moons': 1},{'name': 'jupiter', 'moons': 69}]}>>> spec = T['system']['planets'][-1].values()>>> glom(target, spec)
['jupiter', 69]>>> spec = ('a', (T['b'].items(), list)) # reviewed below>>> glom(target, spec)
[('c', 'd')]

复制代码

4.数据加工

glom不仅仅支持数据的提取,还支持对数据格式化,或者自定义的lambda函数

比如将每个数据的moons求和

复制代码

>>> target = {'system': {'planets': [{'name': 'earth', 'moons': 1},{'name': 'jupiter', 'moons': 69}]}}>>> pprint(glom(target, ('system.planets', ['moons'], sum)}))70

>>> target = {'system': {'planets': [{'name': 'earth', 'moons': 1},{'name': 'jupiter', 'moons': 69}]}}>>> pprint(glom(target, ('system.planets', ['moons'], [lambda x: x*2])}))
[2, 138]

复制代码

5.格式化输出

为了让输出更加有意义,glom提供结构化的2种方法,

字符串

{

    "your name1": 提取路径规则1,

    "your name2": 提取路径规则2,

    "your name3": 提取路径规则3,

}

类 (之后补充)

6.debug调试

如果现有的error输出无法帮你解决bug,那么请使用 glom.Inspect

复制代码

>>> target = {'a': {'b': {}}}>>> val = glom(target, Inspect('a.b')) 
 # wrapping a spec---path: ['a.b']
target: {'a': {'b': {}}}
output: {}---

复制代码

原文出处:https://www.cnblogs.com/Leonharetd/p/9499870.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消