带迭代器接口的流json解析器

jsonslicer的Python项目详细描述


jsonslicer-流json解析器

jsonslicer packaging status

构建状态coverage statuspypi downloadspypi versionpypi pythonsgithub提交(自最新版本起)

概述

jsonslicer执行迭代拉取json 解析,这意味着它不会将整个json加载到内存中 能够解析非常大的json文件或流。这个 模块是用C编写的,使用yajl json解析库,因此它也相当快

jsonslicer接受json映射键或数组索引的路径,并且 提供迭代器接口,生成json数据匹配 给定路径作为完整的python对象。

示例

{"friends":[{"name":"John","age":31},{"name":"Ivan","age":26}],"colleagues":{"manager":{"name":"Jack","age":33},"subordinate":{"name":"Lucy","age":21}}}
fromjsonslicerimportJsonSlicer# Extract specific elements:withopen('people.json')asdata:ivans_age=next(JsonSlicer(data,('friends',1,'age')))# 26withopen('people.json')asdata:managers_name=next(JsonSlicer(data,('colleagues','manager','name')))# 'Jack'# Iterate over collection(s) by using wildcards in the path:withopen('people.json')asdata:forpersoninJsonSlicer(data,('friends',None)):print(person)# {'name': 'John', 'age': 31}# {'name': 'Ivan', 'age': 26}# Iteration over both arrays and dicts is possible, even at the same timewithopen('people.json')asdata:forpersoninJsonSlicer(data,(None,None)):print(person)# {'name': 'John', 'age': 31}# {'name': 'Ivan', 'age': 26}# {'name': 'Jack', 'age': 33}# {'name': 'Lucy', 'age': 21}# Map key of returned objects is available on demand...withopen('people.json')asdata:forposition,personinJsonSlicer(data,('colleagues',None),path_mode='map_keys'):print(position,person)# 'manager' {'name': 'Jack', 'age': 33}# 'subordinate' {'name': 'Lucy', 'age': 21}# ...as well as complete path informationwithopen('people.json')asdata:for*path,personinJsonSlicer(data,(None,None),path_mode='full'):print(path,person)# ('friends', 0) {'name': 'John', 'age': 31})# ('friends', 1) {'name': 'Ivan', 'age': 26})# ('colleagues', 'manager') {'name': 'Jack', 'age': 33})# ('colleagues', 'subordinate') {'name': 'Lucy', 'age': 21})# Extract all instances of deep nested fieldwithopen('people.json')asdata:age_sum=sum(JsonSlicer(data,(None,None,'age')))# 111

API

jsonslicer.JsonSlicer(
    file,
    path_prefix,
    read_size=1024,
    path_mode=None,
    yajl_allow_comments=False,
    yajl_dont_validate_strings=False,
    yajl_allow_trailing_garbage=False,
    yajl_allow_multiple_values=False,
    yajl_allow_partial_values=False,
    encoding=None,
    errors=None,
    binary=False,
)

构造迭代json解析器。它从文件(a.read()-支持类文件对象包含json文档)读取json数据。

file是a.read()-支持 对象 包含json文档。支持二进制和文本文件, 但是二进制的是首选的,因为解析器必须在 无论如何,在内部使用二进制数据,并且使用文本输入将需要 不必要的编码/解码,产生约3%的性能开销。 注意,jsonslicer支持unicode和二进制输出,而不管 输入格式的。

path_prefix是一个iterable(通常是一个列表或元组),指定 解析器应该提取的对象的路径或路径模式 来自JSON。

例如,在上面的示例中,路径('friends',0,'name') WI从根元素降序将产生字符串 按键进入dictionary元素,然后进入数组 按索引元素0,然后按键进入字典元素 "名称"。注意,整数只匹配数组索引和字符串 只匹配字典键。

通过将none指定为 某些路径位置的占位符。例如,(none,none,'name')将产生上述示例中的所有四个名称,因为 它匹配第二个嵌套级别上"name"键下的项 任何数组或映射结构。

无论 输入和输出编码。自动转换 内部使用的格式。

read_size是解析器一次读取的块大小。

path_mode是一个字符串,指定解析器应如何 返回路径信息和对象。以下模式是 支持:

  • 'ignore'(默认值)-不输出任何路径信息,只输出 对象原样('friends')。

    {'name':'John','age':31}{'name':'Ivan','age':26}{'name':'Jack','age':33}{'name':'Lucy','age':21}

    此模式的常用模式是

    forobjectinJsonSlicer(...)
  • "映射键"-遍历数组和元组时按原样输出对象 在遍历地图时由地图键和对象组成。

    {'name':'John','age':31}{'name':'Ivan','age':26}('manager',{'name':'Jack','age':33})('subordinate',{'name':'Lucy','age':21})

    这种格式可能看起来不一致(因此它不是默认的)。 但是在实践中,只有一个类型的集合在 时间和这种类型是已知的,因此这种格式可能是最有用的 在大多数情况下,您需要字典键。

    此模式的常用模式是

    forobjectinJsonSlicer(...)# when iterating arraysforkeyobjectinJsonSlicer(...)# when iterating maps
  • "完整路径"-输出元组由所有路径组件组成 (映射键和数组索引)和作为最后一个元素的对象。

    ('friends',0,{'name':'John','age':31})('friends',1,{'name':'Ivan','age':26})('colleagues','manager',{'name':'Jack','age':33})('colleagues','subordinate',{'name':'Lucy','age':21})

    此模式的常用模式是

    for*path,objectinJsonSlicer(...)

yajl_allow_comments启用相应的yajl标志,即 记录如下:

< Buff行情>

忽略json输入中的javascript样式注释。非标准, 但相当有趣

yajl_dont_validate_strings启用相应的yajl标志,它 记录如下:

< Buff行情>

设置时,解析器将验证json输入中的所有字符串 是有效的utf8,如果不是这样,将发出一个解析错误。什么时候? set,此选项使解析稍微昂贵一些(大约7%取决于 关于正在使用的处理器和编译器)

yajl_allow_trailing_garbage启用相应的yajl标志,它 记录如下:

< Buff行情>

默认情况下,yajl将确保使用整个输入文本 否则将引发错误。启用此标志将导致 Yajl禁用此检查。这在解析json时非常有用 包含多个JSON文档的。

yajl_allow_multiple_values启用相应的yajl标志,它 记录如下:

< Buff行情>

允许一个句柄分析多个值。整个 文本必须是有效的json,并且值可以按任何类型分隔 空白的。这个标志将改变解析器的行为, 并使它在解析值之后继续解析,而不是 正在转换为完整状态。这个选项可能有用 在分析输入流中的多个值时。

yajl_allow_partial_values启用相应的yajl标志,它 记录如下:

< Buff行情>

当调用yajl_complete_parse()时,解析器将检查 顶级值已完全消耗。即,如果在 在解析一个值的过程中,yajl将进入一个错误状态 (EOF过早)。设置此标志将取消该检查和 相应的错误。

编码可用于重写输出编码,输出编码是派生的 如果possib或设置为 python内置的默认值open()将使用(通常'utf-8')。

errors是一个可选字符串,指定如何编码和 要处理解码错误。默认为'strict'

binary强制输出为字节的形式 的字符串。

构造的对象是迭代器。您可以调用next()来提取 其中的单个元素,通过for循环迭代它,或者在生成器中使用它 理解或在接受迭代器的任何地方。

性能/竞争对手

最接近的竞争对手是ijson, 而jsonslicer是为了更好而写的。即,

  • 它比python的原生json模块快15倍,性能类似
  • 它允许在字典上迭代,并允许在 指定要迭代的对象的路径/模式

python 3.7.2/clang 6.0.1/-o2-dndebug/freebsd 12.0amd64/core i7-6600u cpu@2.60ghz的捆绑基准测试结果。

<表><广告>设施键入对象/秒< /广告><正文>json.loads()str1155.9公里json.load(stringio())str1104.1kjsonslicer(无路径、二进制输入、二进制输出)字节1149.5公里jsonslicer(无路径、Unicode输入、二进制输出)字节1121.3公里jsonslicer(无路径、二进制输入、Unicode输出)str1033.3公里jsonslicer(无路径、Unicode输入、Unicode输出)str1006.2公里jsonslicer(完整路径,二进制输出)字节787.6公里jsonslicer(完整路径,Unicode输出)str586.5公里ijson.yajl2\u cffi字节75.7公里ijson.yajl2字节52.0公里ijson.pythonstr32.2公里

状态/待办事项

jsonslicer目前处于beta阶段,用于 报告项目。测试焦点是:

  • 具有不常见编码(输入/输出)配置的边案例
  • 无内存泄漏

要求

  • python 3.4+(不支持python 2)
  • 包配置
  • yajl2.0.3+(旧版本缺少pkgconfig文件)

许可证

麻省理工学院许可证,版权所有(c)2019 dmitry marakasovamdmi3@amdmi3.ru

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
保存一段xml是一个新的xml解析器Java   java如何使用断言测试单链表。assertEquals()   java如何将多个选定图像从Gallery复制到Android中的另一个文件夹   重新触发异常时调用序列中的java差异   swing如何在Java中的GridLayout面板的特定单元格中添加标签?   java在更新引用实体之后,有没有办法更新其他实体中的列?   java如何在两个实体之间使用foreach   java方法add(Component)不适用于参数   Apache Tiles和Spring MVC中的java全局异常页面   java kSoap2发送集合   Java存储对象与直接调用其方法的性能对比?   java如何访问selenium中的nowrap元素   使用endpointsframeworktools生成OpenAPI文档时发生java错误   西/东方向的java JLabel不会显示在BorderLayout中   java ActiveMQ Spring客户端:如何更改处理器池?   java不能取消对void的引用;尝试使用生成器模式   javajavax。websocketclient:如何将大型二进制数据从clientendpoint发送到serverendpoint   运行Java代理时Java代理问题   如何将Web应用程序连接到Java/ABAP应用程序   javajackson处理问题