【Python】JSON的基本使用-JSON 模式(Schema)与数据解析

1、dump和dumps格式化所有的基本数据类型为字符串

plain 复制代码
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类型

plain 复制代码
[] <class 'str'>
2 <class 'str'>
"3" <class 'str'>
{"name": "Tom", "age": 23} <class 'str'>

test.json中的内容

plain 复制代码
{
    "name": "Tom",
    "age": 23
}

2、load和loads将字符串还原为dict

plain 复制代码
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))

运行结果如下:

plain 复制代码
{'name': 'Tom', 'age': 23} <class 'dict'>
{'name': 'Tom', 'age': 23} <class 'dict'>
{'name': 'Tom', 'age': 23} <class 'dict'>

常见的错误:

读取多行的JSON文件

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

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

如果直接使用:

plain 复制代码
with open(json_path, 'r') as f:
        json_data = json.load(f)

就会报错:抛出异常JSONDecodeError。

plain 复制代码
json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 17)

表示数据错误,数据太多,第2行第一列

因为json只能读取一个文档对象,有两个解决办法

1、单行读取文件,一次读取一行文件。

2、保存数据源的时候,格式写为一个对象。

单行读取文件:

plain 复制代码
with open("test.json", "r", encoding='utf-8') as f:
        for line in f.readlines():
            json_data = json.loads(line)

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

plain 复制代码
json.decoder.JSONDecodeError: Expecting value: line 2 column 1 (char 1)

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

plain 复制代码
with open("test.json", "r", encoding='utf-8') as f:
for line in f.readlines():
        line = line.strip()   # 使用strip函数去除空行
        if len(line) != 0:
            json_data = json.loads(line)

合并为一个对象

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

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

然后再用:

plain 复制代码
with open(json_path, 'r') as f:
        json_data = json.loads(f.read())

总结:

json.dumps 将 Python 对象编码成 JSON 字符串

json.loads 将已编码的 JSON 字符串解码为 Python 对象

json.dump和json.load,需要传入文件描述符,加上文件操作。

JSON内部的格式要注意,一个好的格式能够方便读取,可以用indent格式化。

实例:序列化实体对象+

plain 复制代码
def obj_to_json(entity=None):
    """
    序列化实体对象
    :param entity:
    :return:
    """
    json_data = {}
    try:
        data_str = json.dumps(entity, default=lambda obj: obj.__dict__, sort_keys=True, indent=4)
        data = json.loads(data_str)
        json_data = remove_empty_key(data)
    except Exception as e:
        print(e)
    return json_data
plain 复制代码
def remove_empty_key(data):
    if isinstance(data, dict):
        info_re = dict()
        for key, value in data.items():
            if isinstance(value, dict) or isinstance(value, list):
                re = remove_empty_key(value)
                if len(re):
                    info_re[key] = re
            elif value not in [None]:
                info_re[key] = value
        return info_re
    elif isinstance(data, list):
        info_re = list()
        for value in data:
            if isinstance(value, dict) or isinstance(value, list):
                re = remove_empty_key(value)
                if len(re):
                    info_re.append(re)
            elif value not in [None]:
                info_re.append(value)
        return info_re
    else:
        print('输入非列表/字典')
相关推荐
大空大地202619 小时前
流程控制语句--if语句
开发语言
喵手19 小时前
Python爬虫实战:容器化与定时调度实战 - Docker + Cron + 日志轮转 + 失败重试完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·容器化·零基础python爬虫教学·csv导出·定时调度
2601_9491465320 小时前
Python语音通知接口接入教程:开发者快速集成AI语音API的脚本实现
人工智能·python·语音识别
寻梦csdn20 小时前
pycharm+miniconda兼容问题
ide·python·pycharm·conda
毕设源码-邱学长20 小时前
【开题答辩全过程】以 基于PHP的发热病人管理平台的设计与实现为例,包含答辩的问题和答案
开发语言·php
HellowAmy20 小时前
我的C++规范 - 线程池
开发语言·c++·代码规范
独自破碎E20 小时前
【BISHI9】田忌赛马
android·java·开发语言
czy878747520 小时前
const 在 C/C++ 中的全面用法(C/C++ 差异+核心场景+实战示例)
c语言·开发语言·c++
范纹杉想快点毕业20 小时前
实战级ZYNQ中断状态机FIFO设计
java·开发语言·驱动开发·设计模式·架构·mfc
Java面试题总结21 小时前
基于 Java 的 PDF 文本水印实现方案(iText7 示例)
java·python·pdf