介绍
当处理 JSON 数据时,Python 中的 json 模块提供了四个主要的函数:dump、dumps、load 和 loads。这些函数提供了在 JSON 数据和 Python 对象之间进行转换和序列化的功能。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,广泛用于将数据从一个应用程序传输到另一个应用程序。它基于 JavaScript 语言的一个子集,但已成为跨编程语言和平台的通用数据格式。
JSON 数据由键值对组成,类似于 Python 中的字典或 JavaScript 中的对象。它支持以下数据类型:
- 字符串(String):表示文本数据,使用双引号括起来。
- 数字(Number):表示整数或浮点数。
- 布尔值(Boolean):表示真或假。
- 数组(Array):表示有序的值列表,使用方括号括起来,值之间用逗号分隔。
- 对象(Object):表示键值对集合,使用花括号括起来,键和值之间用冒号分隔,键值对之间用逗号分隔。
常用 API
-
**loads() **:将 JSON 字符串解析为 Python 对象。
注意:
- 在使用 loads 的时候 json 中的字符串必须要用双引号,否则会报错(json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 3 column 5 (char 12))
- 入参不能为 None,否则报错
-
dumps() : 将 Python 对象转换为为 JSON 字符串
参数:
-
obj(必需):要编码为 JSON 格式的 Python 数据结构。这可以是字典、列表、整数、字符串等等。
-
ensure_ascii(可选):默认为 True。
- 如果将其设置为 True,则会确保生成的 JSON 字符串中的所有非 ASCII 字符都会被转义为 Unicode 转义序列(例如 \uXXXX),以便在输出时保持 ASCII 字符集。
- 如果将其设置为 False,则非 ASCII 字符将以原始形式保留在输出中。
-
indent(可选):用于指定生成的 JSON 字符串的缩进级别。如果设置为一个整数,将在生成的 JSON 字符串中包含缩进,使其更易于阅读。
-
skipkeys(可选):默认为 False。如果将其设置为 True,则会跳过那些字典键不是基本数据类型(str, int, float, bool, NoneType)的项。如果字典中包含非基本数据类型的键,将会引发 TypeError。
-
check_circular(可选):默认为 True。
- 如果将其设置为 True,则会检查循环引用并引发 ValueError。
- 如果将其设置为 False,则不会检查循环引用。
-
allow_nan(可选):默认为 True。
- 如果将其设置为 True,则允许编码浮点数值为特殊值(如 NaN 和 Infinity),这符合 JSON 规范。
- 如果将其设置为 False,则将 NaN 和 Infinity 视为无效输入,并引发 ValueError。
-
cls(可选):用于指定自定义 JSON 编码器的类。默认为 None,表示使用标准的 JSON 编码器。
-
separators(可选):用于指定生成的 JSON 字符串中的分隔符。
默认为 (
", "
,": "
),表示键值对之间使用逗号和冒号分隔。可以根据需要自定义分隔符。
import json str = ''' [{ "name":"AnJing", "age":"26" }] ''' data = json.loads(str) print(data) # 输出:[{'name': 'AnJing', 'age': '26'}] print(type(data)) # 输出:<class 'list'> print(data[0].get('name')) # 输出:AnJing print(data[0]['name']) # 通过下标进行选择 str_data = json.dumps(data) print(type(data)) # 输出:<class 'str'> print(data) # 输出:[{"name": "AnJing", "age": "26"}]
-
-
load() :从 JSON 文件中读取数据,并将其解析为 Python 对象。
它接受一个参数:要读取的文件对象。
-
dump() :将 Python 对象转换为 JSON 数据,并将其写入文件对象中
它接受两个参数:要序列化的对象和目标文件对象
注意:在使用 dump 和 load 函数时,需要提供文件对象并确保文件以适当的模式打开(如 ‘w’ 用于写入,‘r’ 用于读取)
import json str = [{ "name":"AnJing", "age":"26" }] # 通过dump写入到文件中 json.dump(str, open('123.json','w')) # 通过load查看是否写入 data = json.load(open('123.json','r')) print(data) # 输出:[{'name': 'AnJing', 'age': '26'}]
常见报错
-
解析无效的 JSON 字符串
如果提供的 JSON 数据无效,解析过程将引发 JSONDecodeError 异常。
例如:
-
缺少引号
invalid_json = '{"name": "ZhangSan", age: 30, "city": "ShenZhen"}' data = json.loads(invalid_json) # 引发JSONDecodeError异常。原因为JSON字符串中的age缺少双引号,导致解析失败
-
不符合 JSON 语法规则(JSON 数据内字符串必须使用双引号)
-
-
解析无效属性的字符串
如果方法入参为 None 或空字符串灯,解析过程将引发 AttributeError 错误
-
访问不存在的键
如果尝试访问 JSON 数据中不存在的键,将引发 KeyError 异常。
print(data['address']) # 引发KeyError异常。原因为JSON数据中没有address键,访问该键将引发异常
获取对象去除为 null 的字段的 json 字符串
-
要将一个包含基本模型的对象转换为 JSON 并去除其中的
null
字段,可以使用 Python 中的json
模块和一个递归函数来完成这个任务。 -
示例代码
import json def remove_null(obj): if isinstance(obj, dict): return {key: remove_null(value) for key, value in obj.items() if value is not None} elif isinstance(obj, list): return [remove_null(item) for item in obj if item is not None] else: return obj # 示例对象,包含了一些 None 值 data = { "name": "John", "age": None, "address": { "street": "123 Main St", "city": None, "zip_code": "98765" }, "hobbies": ["reading", None, "swimming"] } # 使用 remove_null 函数去除 None 值 data_without_null: dict = remove_null(data) # 将处理后的对象转换为 JSON 格式 json_data = json.dumps(data_without_null) # 注意:继承自pydantic的BaseModel类的类,若有字段的类型也是BaseModel,需先转json再转dict,再传入函数 json_data = json.dumps(remove_null(json.loads(base_model.josn())))