扩展python json包功能

jsonextended的Python项目详细描述


json扩展

Build StatusCoverage StatusDocumentation StatusPyPIAnaconda-Server Badge

扩展python json包功能的模块:

  • 将目录结构视为嵌套字典:
    • 轻量级插件系统:为 分析不同的文件扩展名(在框中:.json、.csv、.hdf5) 以及编码/解码对象
    • 延迟加载:仅当文件被索引到
    • tab completion:索引为选项卡,用于快速浏览数据
  • 嵌套词典的操作:
    • 增强的漂亮打印机
    • jupyter笔记本中的javascript呈现的可扩展树
    • 函数包括:filter、merge、flatten、unflatten、diff
    • 输出到目录结构(属于n文件夹级别)
  • <> LI>大型JSON文件的磁盘索引选项(使用IJSON包)
  • 应用和转换物理单位的单位模式概念(使用PINT软件包)

文档https://jsonextended.readthedocs.io

内容

安装

来自conda(推荐):

conda install -c conda-forge jsonextended

来自PYPI:

pip install jsonextended

jsonextended不依赖于python 3.x并且只依赖于python3.x pathlib2在2.7上,但是,为了获得完整的功能,建议安装 以下软件包:

conda install -c conda-forge ijson numpy pint h5py pandas

基本示例

from jsonextended import edict, plugins, example_mockpaths

采用目录结构,可能包含多个文件类型:

datadir = example_mockpaths.directory1
print(datadir.to_string(indentlvl=3,file_content=True))
Folder("dir1")
   File("file1.json") Contents:
    {"key2": {"key3": 4, "key4": 5}, "key1": [1, 2, 3]}
   Folder("subdir1")
     File("file1.csv") Contents:
       # a csv file
      header1,header2,header3
      val1,val2,val3
      val4,val5,val6
      val7,val8,val9
     File("file1.literal.csv") Contents:
       # a csv file with numbers
      header1,header2,header3
      1,1.1,string1
      2,2.2,string2
      3,3.3,string3
   Folder("subdir2")
     Folder("subsubdir21")
       File("file1.keypair") Contents:
         # a key-pair file
        key1 val1
        key2 val2
        key3 val3
        key4 val4

可以为解析每种文件类型定义插件(请参见Creating Plugins部分):

plugins.load_builtin_plugins('parsers')
plugins.view_plugins('parsers')
{'csv.basic': 'read *.csv delimited file with headers to {header:[column_values]}',
 'csv.literal': 'read *.literal.csv delimited files with headers to {header:column_values}, with number strings converted to int/float',
 'hdf5.read': 'read *.hdf5 (in read mode) files using h5py',
 'json.basic': 'read *.json files using json.load',
 'keypair': "read *.keypair, where each line should be; '<key> <pair>'"}

然后lazyload获取一个路径名、类似路径的对象或类似dict的对象, 它会懒洋洋地用一个兼容的插件加载每个文件。

lazy = edict.LazyLoad(datadir)
lazy
{file1.json:..,subdir1:..,subdir2:..}

然后可以将lazyload视为字典,或按tab索引 完成时间:

list(lazy.keys())
['subdir1', 'subdir2', 'file1.json']
lazy[['file1.json','key1']]
[1, 2, 3]
lazy.subdir1.file1_literal_csv.header2
[1.1, 2.2, 3.3]

为了漂亮地打印字典:

edict.pprint(lazy,depth=2)
file1.json:
  key1: [1, 2, 3]
  key2: {...}
subdir1:
  file1.csv: {...}
  file1.literal.csv: {...}
subdir2:
  subsubdir21: {...}

存在许多函数来操作嵌套字典:

edict.flatten(lazy.subdir1)
{('file1.csv', 'header1'): ['val1', 'val4', 'val7'],
 ('file1.csv', 'header2'): ['val2', 'val5', 'val8'],
 ('file1.csv', 'header3'): ['val3', 'val6', 'val9'],
 ('file1.literal.csv', 'header1'): [1, 2, 3],
 ('file1.literal.csv', 'header2'): [1.1, 2.2, 3.3],
 ('file1.literal.csv', 'header3'): ['string1', 'string2', 'string3']}

lazyload将plugins.decode函数解析为解析器插件的 read_file方法(关键字“object_hook”)。因此,定制解码器 可以为特定的字典密钥签名设置插件:

print(example_mockpaths.jsonfile2.to_string())
File("file2.json") Contents:
{"key1":{"_python_set_": [1, 2, 3]},"key2":{"_numpy_ndarray_": {"dtype": "int64", "value": [1, 2, 3]}}}
edict.LazyLoad(example_mockpaths.jsonfile2).to_dict()
{u'key1': {u'_python_set_': [1, 2, 3]},
 u'key2': {u'_numpy_ndarray_': {u'dtype': u'int64', u'value': [1, 2, 3]}}}
plugins.load_builtin_plugins('decoders')
plugins.view_plugins('decoders')
{'decimal.Decimal': 'encode/decode Decimal type',
 'numpy.ndarray': 'encode/decode numpy.ndarray',
 'pint.Quantity': 'encode/decode pint.Quantity object',
 'python.set': 'decode/encode python set'}
dct = edict.LazyLoad(example_mockpaths.jsonfile2).to_dict()
dct
{u'key1': {1, 2, 3}, u'key2': array([1, 2, 3])}

使用编码器插件,可以反转此过程:

plugins.load_builtin_plugins('encoders')
plugins.view_plugins('encoders')
{'decimal.Decimal': 'encode/decode Decimal type',
 'numpy.ndarray': 'encode/decode numpy.ndarray',
 'pint.Quantity': 'encode/decode pint.Quantity object',
 'python.set': 'decode/encode python set'}
import json
json.dumps(dct,default=plugins.encode)
'{"key2": {"_numpy_ndarray_": {"dtype": "int64", "value": [1, 2, 3]}}, "key1": {"_python_set_": [1, 2, 3]}}'

创建和加载插件

from jsonextended import plugins, utils

插件被识别为具有最小属性集的类 匹配插件类别界面:

plugins.view_interfaces()
{'decoders': ['plugin_name', 'plugin_descript', 'dict_signature'],
 'encoders': ['plugin_name', 'plugin_descript', 'objclass'],
 'parsers': ['plugin_name', 'plugin_descript', 'file_regex', 'read_file']}
plugins.unload_all_plugins()
plugins.view_plugins()
{'decoders': {}, 'encoders': {}, 'parsers': {}}

例如,一个简单的解析器插件是:

class ParserPlugin(object):
    plugin_name = 'example'
    plugin_descript = 'a parser for *.example files, that outputs (line_number:line)'
    file_regex = '*.example'
    def read_file(self, file_obj, **kwargs):
        out_dict = {}
        for i, line in enumerate(file_obj):
            out_dict[i] = line.strip()
        return out_dict

插件可以作为类加载:

plugins.load_plugin_classes([ParserPlugin],'parsers')
plugins.view_plugins()
{'decoders': {},
 'encoders': {},
 'parsers': {'example': 'a parser for *.example files, that outputs (line_number:line)'}}

或按目录(加载所有.py文件):

fobj = utils.MockPath('example.py',is_file=True,content="""
class ParserPlugin(object):
    plugin_name = 'example.other'
    plugin_descript = 'a parser for *.example.other files, that outputs (line_number:line)'
    file_regex = '*.example.other'
    def read_file(self, file_obj, **kwargs):
        out_dict = {}
        for i, line in enumerate(file_obj):
            out_dict[i] = line.strip()
        return out_dict
""")
dobj = utils.MockPath(structure=[fobj])
plugins.load_plugins_dir(dobj,'parsers')
plugins.view_plugins()
{'decoders': {},
 'encoders': {},
 'parsers': {'example': 'a parser for *.example files, that outputs (line_number:line)',
  'example.other': 'a parser for *.example.other files, that outputs (line_number:line)'}}

有关更复杂的解析器示例,请参见 jsonextended.complex_parsers

接口规范

  • 分析器:
    • file_regex属性,一个str,指示应用它的文件 到。一个文件将被它匹配的最长正则表达式解析。
    • read_file方法,它接受(打开的)文件对象和 Kwargs作为参数
  • 解码器:
    • dict_signature属性,表示 字典必须有,例如dict_signature=('a','b')解码{'a':1,'b':2}
    • 来自…方法,将dict对象作为参数。 plugins.decode函数将使用 intype参数,例如如果intype='json',则from_json将 被召唤。
  • 编码器:
    • objClass属性,应用编码的对象类, 例如objClass=decimal.decimal对该类型的对象进行编码
    • 到…方法,将dict对象作为参数。这个 plugins.encode函数将使用 outtype参数,例如如果outtype='json',则将调用to_json

扩展示例

有关详细信息,所有函数都包含 例子。

数据文件夹初始化

from jsonextended import ejson, edict, utils
path = utils.get_test_path()
ejson.jkeys(path)
['dir1', 'dir2', 'dir3']
jdict1 = ejson.to_dict(path)
edict.pprint(jdict1,depth=2)
dir1:
  dir1_1: {...}
  file1: {...}
  file2: {...}
dir2:
  file1: {...}
dir3:
edict.to_html(jdict1,depth=2)

要尝试呈现的json树,请在jupyter笔记本中输出,请转到: https://chrisjsewell.github.io/

嵌套字典操作

jdict2 = ejson.to_dict(path,['dir1','file1'])
edict.pprint(jdict2,depth=1)
initial: {...}
meta: {...}
optimised: {...}
units: {...}
filtered = edict.filter_keys(jdict2,['vol*'],use_wildcards=True)
edict.pprint(filtered)
initial:
  crystallographic:
    volume: 924.62752781
  primitive:
    volume: 462.313764
optimised:
  crystallographic:
    volume: 1063.98960509
  primitive:
    volume: 531.994803
edict.pprint(edict.flatten(filtered))
(initial, crystallographic, volume):   924.62752781
(initial, primitive, volume):          462.313764
(optimised, crystallographic, volume): 1063.98960509
(optimised, primitive, volume):        531.994803

单位模式

from jsonextended.units import apply_unitschema, split_quantities
withunits = apply_unitschema(filtered,{'volume':'angstrom^3'})
edict.pprint(withunits)
initial:
  crystallographic:
    volume: 924.62752781 angstrom ** 3
  primitive:
    volume: 462.313764 angstrom ** 3
optimised:
  crystallographic:
    volume: 1063.98960509 angstrom ** 3
  primitive:
    volume: 531.994803 angstrom ** 3
newunits = apply_unitschema(withunits,{'volume':'nm^3'})
edict.pprint(newunits)
initial:
  crystallographic:
    volume: 0.92462752781 nanometer ** 3
  primitive:
    volume: 0.462313764 nanometer ** 3
optimised:
  crystallographic:
    volume: 1.06398960509 nanometer ** 3
  primitive:
    volume: 0.531994803 nanometer ** 3
edict.pprint(split_quantities(newunits),depth=4)
initial:
  crystallographic:
    volume:
      magnitude: 0.92462752781
      units:     nanometer ** 3
  primitive:
    volume:
      magnitude: 0.462313764
      units:     nanometer ** 3
optimised:
  crystallographic:
    volume:
      magnitude: 1.06398960509
      units:     nanometer ** 3
  primitive:
    volume:
      magnitude: 0.531994803
      units:     nanometer ** 3

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

推荐PyPI第三方库


热门话题
java Android测试运行失败:没有测试结果   java设置JMenuItems与Nimbus LaF的边界   java是使用springboot、Crudepository和MySQL检查重复值的好方法吗   谷歌电子表格的Java时代日期   java向xml文件添加EditText不起作用   java ORA00933:SQL命令未正确结束WHERE子句   如何在java中防止JTextField上使用CTRL+C?   java绑定到TypeLiteral在google guice中是好的还是坏的做法   java找到了原始类型,缺少泛型类的返回参数   Kafka Streams API中ArrayList Serde的java问题   java在hibernate中,哪种持久化上下文的性能更好?   java通过本机查询获取数据库url、名称和模式版本   如何为Java枚举编写通用for循环?   在Java应用程序中播放MP3   如何使用VisualVM度量短时间运行的Java应用程序的性能?   java从当前日期获取datetime(秒)   简单JMH基准中的javagrpcoome和NPE   java如何加载Maven项目库中Spring jar的应用程序上下文   JavaCC XPath解析器   用于Scala和Java的类型安全生成器库