JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,简洁易读且跨语言兼容,在 Python 中处理 JSON 数据主要依赖内置的json模块。本文从基础到实战,详解 Python3 解析 JSON 的核心方法、常见场景和避坑技巧。
JSON 本质是一种字符串格式,用来表示结构化数据,比如:
{
"name": "张三",
"age": 25,
"is_student": false,
"hobbies": ["篮球", "编程"],
"scores": {"math": 90, "english": 85}
}
它和 Python 数据类型的对应关系非常重要(转换时会自动映射):
Python 的json模块提供了 4 个核心函数,实现 “Python 对象↔JSON 字符串” 的相互转换:
将 Python 的字典、列表等对象转换为 JSON 格式(称为 “编码”),用dumps()或dump()。
import json
data = {
"name": "张三",
"age": 25,
"is_student": False,
"hobbies": ["篮球", "编程"],
"scores": {"math": 90, "english": 85},
"address": None
}
json_str = json.dumps(data)
print(json_str)
注意:
- 中文会被默认转为 Unicode 编码(如
"张三"→"u5f20u4e09"),如需保留中文,加ensure_ascii=False参数:json_str = json.dumps(data, ensure_ascii=False)
print(json_str)
- 生成的 JSON 字符串中,字符串必须用双引号(JSON 规范),Python 中的单引号会被自动转为双引号。
默认生成的 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
}
}
如果需要将 JSON 数据保存到文件,直接用dump()更方便(无需先转字符串):
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
执行后会生成data.json文件,内容就是格式化后的 JSON。
将 JSON 字符串或 JSON 文件转换为 Python 对象(称为 “解码”),用loads()或load()。
import json
json_str = '''
{
"name": "张三",
"age": 25,
"is_student": false,
"hobbies": ["篮球", "编程"],
"scores": {"math": 90, "english": 85},
"address": null
}
'''
data = json.loads(json_str)
print(type(data))
print(data["name"])
print(data["hobbies"][0])
print(data["scores"]["math"])
直接读取 JSON 文件并转换为 Python 对象:
with open("data.json", "r", encoding="utf-8") as f:
data = json.load(f)
print(data["age"])
JSON 仅支持基础数据类型(字符串、数字、布尔、数组、对象、null),如果 Python 对象包含datetime、自定义类等复杂类型,直接转换会报错。需要自定义 “编码器” 和 “解码器”。
JSON 不支持datetime,需转为字符串(如 ISO 格式)再编码:
import json
from datetime import datetime
data = {
"name": "张三",
"birthdate": datetime(1999, 10, 1)
}
class DateTimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
json_str = json.dumps(data, cls=DateTimeEncoder, ensure_ascii=False)
print(json_str)
将 JSON 中的日期字符串转回datetime对象:
from datetime import datetime
json_str = '{"name": "张三", "birthdate": "1999-10-01T00:00:00"}'
def datetime_decoder(obj):
if "birthdate" in obj:
obj["birthdate"] = datetime.fromisoformat(obj["birthdate"])
return obj
data = json.loads(json_str, object_hook=datetime_decoder)
print(type(data["birthdate"]))
print(data["birthdate"].year)
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 格式规范,避免解析错误。

