zoukankan      html  css  js  c++  java
  • 【Python】json格式数据解码为python对象;Python对象进行JSON格式的编码

    JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。Python3 中可以使用 json 模块来对 JSON 数据进行编解码,它主要提供了四个方法: dumpsdumploadsload

    dump和dumps

    • dump和dumps对python对象进行序列化。将一个Python对象进行JSON格式的编码。

    dump函数:

    json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
    

    obj: 表示是要序列化的对象。
    fp: 文件描述符,将序列化的str保存到文件中。json模块总是生成str对象,而不是字节对象;因此,fp.write()必须支持str输入。
    skipkeys: 默认为False,如果skipkeysTrue,(默认值:False),则将跳过不是基本类型(str,int,float,bool,None)的dict键,不会引发TypeError。
    ensure_ascii: 默认值为True,能将所有传入的非ASCII字符转义输出。如果ensure_ascii为False,则这些字符将按原样输出。
    check_circular:默认值为True,如果check_circular为False,则将跳过对容器类型的循环引用检查,循环引用将导致OverflowError。
    allow_nan: 默认值为True,如果allow_nan为False,则严格遵守JSON规范,序列化超出范围的浮点值(nan,inf,-inf)会引发ValueError。 如果allow_nan为True,则将使用它们的JavaScript等效项(NaN,Infinity,-Infinity)。
    indent: 设置缩进格式,默认值为None,选择的是最紧凑的表示。如果indent是非负整数或字符串,那么JSON数组元素和对象成员将使用该缩进级别进行输入;indent为0,负数或“”仅插入换行符;indent使用正整数缩进多个空格;如果indent是一个字符串(例如“ ”),则该字符串用于缩进每个级别。
    separators: 去除分隔符后面的空格,默认值为None,如果指定,则分隔符应为(item_separator,key_separator)元组。如果缩进为None,则默认为(’,’,’:’);要获得最紧凑的JSON表示,可以指定(’,’,’:’)以消除空格。
    default: 默认值为None,如果指定,则default应该是为无法以其他方式序列化的对象调用的函数。它应返回对象的JSON可编码版本或引发TypeError。如果未指定,则引发TypeError。
    sort_keys: 默认值为False,如果sort_keys为True,则字典的输出将按键值排序。

    dumps函数:

    json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
    
    • dumps函数不需要传文件描述符,其他的参数和dump函数的一样

    load和loads

    json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
    

    fp: 文件描述符,将fp(.read()支持包含JSON文档的文本文件或二进制文件)反序列化为Python对象。
    object_hook: 默认值为None,object_hook是一个可选函数,此功能可用于实现自定义解码器。指定一个函数,该函数负责把反序列化后的基本类型对象转换成自定义类型的对象。
    parse_float: 默认值为None,如果指定了parse_float,用来对JSON float字符串进行解码,这可用于为JSON浮点数使用另一种数据类型或解析器。
    parse_int: 默认值为None,如果指定了parse_int,用来对JSON int字符串进行解码,这可以用于为JSON整数使用另一种数据类型或解析器。
    parse_constant:默认值为None,如果指定了parse_constant,对-Infinity,Infinity,NaN字符串进行调用。如果遇到了无效的JSON符号,会引发异常。

    • 如果进行反序列化(解码)的数据不是一个有效的JSON文档,将会引发 JSONDecodeError异常。

    loads函数:

    json.loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
    

    s: 将s(包含JSON文档的str,bytes或bytearray实例)反序列化为Python对象。
    encoding: 指定一个编码的格式。
    loads也不需要文件描述符,其他参数的含义和load函数的一致。

    格式转化表

    JSON中的数据格式和Python中的数据格式转化关系如下:

    JSON Python
    object dict
    array list
    string str
    number (int) int
    number (real) float
    true True
    false False
    null None

    实战:

    dump和dumps

    import json
    # dumps可以格式化所有的基本数据类型为字符串
    data1 = json.dumps([])         # 列表
    print(data1, type(data1))
    data2 = json.dumps(2)          # 数字
    print(data2, type(data2))
    data3 = json.dumps('3')        # 字符串
    print(data3, type(data3))
    dict = {"name": "Tom", "age": 23}   # 字典
    data4 = json.dumps(dict)
    print(data4, type(data4))
    
    with open("test.json", "w", encoding='utf-8') as f:
        # indent 超级好用,格式化保存字典,默认为None,小于0为零个空格
        f.write(json.dumps(dict, indent=4))
        json.dump(dict, f, indent=4)  # 传入文件描述符,和dumps一样的结果
    

    得到的输出结果如下:格式化所有的数据类型为str类型

    [] <class 'str'>
    2 <class 'str'>
    "3" <class 'str'>
    {"name": "Tom", "age": 23} <class 'str'>
    

    test.json中的内容

    {
        "name": "Tom",
        "age": 23
    }
    

    load和loads

    import json
    
    dict = '{"name": "Tom", "age": 23}'   # 将字符串还原为dict
    data1 = json.loads(dict)
    print(data1, type(data1))
    
    with open("test.json", "r", encoding='utf-8') as f:
        data2 = json.loads(f.read())    # load的传入参数为字符串类型
        print(data2, type(data2))
        f.seek(0)                       # 将文件游标移动到文件开头位置
        data3 = json.load(f)
        print(data3, type(data3))
    

    运行结果如下:

    {'name': 'Tom', 'age': 23} <class 'dict'>
    {'name': 'Tom', 'age': 23} <class 'dict'>
    {'name': 'Tom', 'age': 23} <class 'dict'>
    

    常见的错误:

    读取多行的JSON文件
    假如要读取一个多行的JSON文件:

    {"坂": ["坂5742"]}
    {"构": ["构6784"]}
    {"共": ["共5171"]}
    {"钩": ["钩94a9"]}
    {"肮": ["肮80ae"]}
    {"孤": ["孤5b64"]}
    

    如果直接使用:

    with open(json_path, 'r') as f:
        json_data = json.load(f)
    

    就会报错:抛出异常JSONDecodeError。

    json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 17)
    

    表示数据错误,数据太多,第2行第一列
    因为json只能读取一个文档对象,有两个解决办法
    1、单行读取文件,一次读取一行文件。
    2、保存数据源的时候,格式写为一个对象。
    单行读取文件:

    with open(json_path, 'r') as f:
        for line in f.readlines():
            json_data = json.loads(line)
    

    但是这种做法还有个问题,如果JSON文件中包含空行,还是会抛出JSONDecodeError异常

    json.decoder.JSONDecodeError: Expecting value: line 2 column 1 (char 1)
    

    可以先处理空行,再进行文件读取操作:

    for line in f.readlines():
        line = line.strip()   # 使用strip函数去除空行
            if len(line) != 0:
                json_data = json.loads(line)
    

    将json文件处理成一个对象文件。

    {"dict": [
    {"坂": ["坂5742"]},
    {"构": ["构6784"]},
    {"共": ["共5171"]},
    {"钩": ["钩94a9"]},
    {"肮": ["肮80ae"]},
    {"孤": ["孤5b64"]}
    ]}
    

    然后再用:

    with open(json_path, 'r') as f:
        json_data = json.loads(f.read())
    

    总结:
    json.dumps 将 Python 对象编码成 JSON 字符串
    json.loads 将已编码的 JSON 字符串解码为 Python 对象
    json.dumpjson.load,需要传入文件描述符,加上文件操作。
    JSON内部的格式要注意,一个好的格式能够方便读取,可以用indent格式化。

  • 相关阅读:
    python 线程队列、线程池、全局解释器锁GIL
    java Cookie 获取历史记录列表(三)
    Java中如何读写cookie (二)
    java读取和写入浏览器Cookies
    zookeeper的安装和部署
    Spring Boot 多模块项目创建与配置 (一)
    十款效果惊艳的Html案例(一)
    phython
    阿里高并发所用到的技术
    Java9新特性
  • 原文地址:https://www.cnblogs.com/jianxiaochong/p/14844275.html
Copyright © 2011-2022 走看看