Python3 JSON 数据解析详解
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,简洁易读且跨语言兼容,在 Python 中处理 JSON 数据主要依赖内置的
二、核心工具:
1. 基础用法:
2. 美化 JSON:
3. 写入文件:
1. 解析 JSON 字符串:
2. 读取 JSON 文件:
1. 处理
2. 解析
json模块。本文从基础到实战,详解 Python3 解析 JSON 的核心方法、常见场景和避坑技巧。
一、先搞懂:JSON 是什么?和 Python 数据类型有啥对应关系?
JSON 本质是一种字符串格式,用来表示结构化数据,比如:
{
"name": "张三",
"age": 25,
"is_student": false,
"hobbies": ["篮球", "编程"],
"scores": {"math": 90, "english": 85}
}
它和 Python 数据类型的对应关系非常重要(转换时会自动映射):
| JSON 类型 | Python 类型 | 说明 |
|---|---|---|
对象({}) |
字典(dict) |
键值对集合 |
数组([]) |
列表(list) |
有序元素集合 |
字符串("") |
字符串(str) |
必须用双引号(JSON 规范) |
| 数字(整数) | 整数(int) |
如123→123 |
| 数字(浮点数) | 浮点数(float) |
如3.14→3.14 |
true |
True |
布尔值真 |
false |
False |
布尔值假 |
null |
None |
空值 |
二、核心工具:json模块的 4 个核心函数
Python 的
json模块提供了 4 个核心函数,实现 “Python 对象↔JSON 字符串” 的相互转换:| 函数 | 作用 | 适用场景 |
|---|---|---|
json.dumps() |
Python 对象→JSON 字符串(内存中转换) | 需要在代码中处理 JSON 字符串时 |
json.dump() |
Python 对象→JSON 文件(直接写入文件) | 需要将 JSON 保存到文件时 |
json.loads() |
JSON 字符串→Python 对象(内存中转换) | 处理已获取的 JSON 字符串时 |
json.load() |
JSON 文件→Python 对象(直接读取文件) | 读取 JSON 文件内容时 |
三、实战:从 Python 对象到 JSON(编码)
将 Python 的字典、列表等对象转换为 JSON 格式(称为 “编码”),用
dumps()或dump()。1. 基础用法:json.dumps()生成 JSON 字符串
import json
# 定义一个Python字典(包含多种类型)
data = {
"name": "张三",
"age": 25,
"is_student": False,
"hobbies": ["篮球", "编程"],
"scores": {"math": 90, "english": 85},
"address": None # 对应JSON的null
}
# 将Python对象转为JSON字符串
json_str = json.dumps(data)
print(json_str)
# 输出:{"name": "\u5f20\u4e09", "age": 25, "is_student": false, "hobbies": ["\u7篮球", "\u7f16\u7a0b"], "scores": {"math": 90, "english": 85}, "address": null}
注意:
- 中文会被默认转为 Unicode 编码(如
"张三"→"\u5f20\u4e09"),如需保留中文,加ensure_ascii=False参数:json_str = json.dumps(data, ensure_ascii=False) print(json_str) # 中文正常显示 - 生成的 JSON 字符串中,字符串必须用双引号(JSON 规范),Python 中的单引号会被自动转为双引号。
2. 美化 JSON:indent和sort_keys参数
默认生成的 JSON 是紧凑的单行字符串,用
indent设置缩进可美化格式,sort_keys=True可按键名排序:json_str = json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True)
print(json_str)
输出(格式化后更易读):
{
"address": null,
"age": 25,
"hobbies": [
"篮球",
"编程"
],
"is_student": false,
"name": "张三",
"scores": {
"english": 85,
"math": 90
}
}
3. 写入文件:json.dump()
如果需要将 JSON 数据保存到文件,直接用
dump()更方便(无需先转字符串): with open("data.json", "w", encoding="utf-8") as f:
# 直接将Python对象写入文件,ensure_ascii=False保留中文
json.dump(data, f, ensure_ascii=False, indent=2)
执行后会生成
data.json文件,内容就是格式化后的 JSON。四、实战:从 JSON 到 Python 对象(解码)
将 JSON 字符串或 JSON 文件转换为 Python 对象(称为 “解码”),用
loads()或load()。1. 解析 JSON 字符串:json.loads()
import json
# 定义一个JSON字符串(注意用双引号)
json_str = '''
{
"name": "张三",
"age": 25,
"is_student": false,
"hobbies": ["篮球", "编程"],
"scores": {"math": 90, "english": 85},
"address": null
}
'''
# 将JSON字符串转为Python对象(字典)
data = json.loads(json_str)
print(type(data)) # <class 'dict'>
print(data["name"]) # 张三
print(data["hobbies"][0]) # 篮球
print(data["scores"]["math"]) # 90
2. 读取 JSON 文件:json.load()
直接读取 JSON 文件并转换为 Python 对象:
with open("data.json", "r", encoding="utf-8") as f:
data = json.load(f) # 直接从文件加载并转换
print(data["age"]) # 25
五、高级场景:处理复杂类型(如日期、自定义对象)
JSON 仅支持基础数据类型(字符串、数字、布尔、数组、对象、null),如果 Python 对象包含
datetime、自定义类等复杂类型,直接转换会报错。需要自定义 “编码器” 和 “解码器”。1. 处理datetime类型(编码)
JSON 不支持
datetime,需转为字符串(如 ISO 格式)再编码:import json
from datetime import datetime
# 定义包含datetime的Python对象
data = {
"name": "张三",
"birthdate": datetime(1999, 10, 1)
}
# 自定义编码器:将datetime转为ISO字符串
class DateTimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat() # 转为"1999-10-01T00:00:00"
return super().default(obj) # 其他类型用默认处理
# 用自定义编码器转换
json_str = json.dumps(data, cls=DateTimeEncoder, ensure_ascii=False)
print(json_str)
# 输出:{"name": "张三", "birthdate": "1999-10-01T00:00:00"}
2. 解析datetime字符串(解码)
将 JSON 中的日期字符串转回
datetime对象:from datetime import datetime
# 定义JSON字符串(包含日期字符串)
json_str = '{"name": "张三", "birthdate": "1999-10-01T00:00:00"}'
# 自定义解码器:将字符串转为datetime
def datetime_decoder(obj):
if "birthdate" in obj:
obj["birthdate"] = datetime.fromisoformat(obj["birthdate"])
return obj
# 用object_hook参数指定解码器
data = json.loads(json_str, object_hook=datetime_decoder)
print(type(data["birthdate"])) # <class 'datetime.datetime'>
print(data["birthdate"].year) # 1999
六、避坑指南:常见错误与解决
-
JSON 字符串格式错误(最常见)
错误:JSON 中用单引号(如{'name': '张三'}),或键不是字符串(如{123: "value"})。
解决:严格遵守 JSON 规范 —— 字符串用双引号,键必须是字符串。 -
解析无效 JSON 时的报错
错误:json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes
解决:检查 JSON 格式,用try-except捕获错误:try: data = json.loads(invalid_json_str) except json.JSONDecodeError as e: print(f"JSON解析错误:{e}") -
复杂类型未处理导致的编码错误
错误:TypeError: Object of type datetime is not JSON serializable
解决:自定义编码器(如上文的DateTimeEncoder),将复杂类型转为基础类型。
七、总结
Python 处理 JSON 的核心是
json模块的 4 个函数:- 编码(Python→JSON):
dumps()(转字符串)、dump()(写文件); - 解码(JSON→Python):
loads()(解析字符串)、load()(读文件)。
关键注意点:
- 牢记 JSON 与 Python 类型的对应关系;
- 中文处理需加
ensure_ascii=False; - 复杂类型(如
datetime)需自定义编码 / 解码器; - 严格遵守 JSON 格式规范,避免解析错误。
浙公网安备 33010602011771号