Python: JSON 数据处理
JSON(JavaScript Object Notation)是 Web 上最通用的数据交换格式。几乎所有 Web API 都返回 JSON 数据。Python 的
json模块可以轻松地在 Python 对象和 JSON 字符串之间转换。
1. Python 对象 ↔ JSON 字符串
▶ 示例:序列化为 JSON 字符串
PYTHON
import json
# Python 字典 → JSON 字符串(序列化)
data = {
"name": "Alice",
"age": 25,
"is_student": False,
"scores": [85, 92, 78],
"address": None
}
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)
输出:
TEXT
📖 仅展示
# 执行成功
运行结果:
JSON
{
"name": "Alice",
"age": 25,
"is_student": false,
"scores": [85, 92, 78],
"address": null
}
💡
ensure_ascii=False 很重要: 不加这个参数,中文字符会被转成 Unicode 编码(\u5f20\u4e09)。加上后保留原始中文。indent=2 让输出格式化,方便阅读。生产环境中可以用 indent=None 压缩成一行,节省带宽。
2. JSON 字符串 → Python 对象(反序列化)
▶ 示例:反序列化 JSON 字符串
PYTHON
import json
json_str = '{"name": "Alice", "age": 25, "is_student": false, "scores": [85, 92, 78]}'
data = json.loads(json_str)
print(data) # {'name': 'Alice', 'age': 25, ...}
print(type(data)) # <class 'dict'>
print(data["name"]) # Alice
print(data["scores"][0]) # 85
输出:
TEXT
📖 仅展示
# 执行成功
(1) JSON 类型与 Python 类型的对应
| JSON | Python |
|---|---|
string |
str |
number |
int / float |
boolean |
bool |
null |
None |
array |
list |
object |
dict |
3. JSON 文件读写
▶ 示例:JSON 文件读写
PYTHON
import json
# 写入 JSON 文件
data = {
"students": [
{"name": "Alice", "age": 20, "score": 85},
{"name": "Bob", "age": 21, "score": 92},
{"name": "Charlie", "age": 19, "score": 78}
]
}
with open("students.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# 读取 JSON 文件
with open("students.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print(f"学生人数:{len(loaded['students'])}")
for s in loaded["students"]:
print(f" {s['name']}: {s['score']}分")
输出:
TEXT
📖 仅展示
# 执行成功
▶ 示例:数据持久化(难度⭐⭐)
PYTHON
import json
import os
DATA_FILE = "notes.json"
def load_notes():
"""从 JSON 文件加载笔记"""
if not os.path.exists(DATA_FILE):
return []
with open(DATA_FILE, "r", encoding="utf-8") as f:
return json.load(f)
def save_notes(notes):
"""保存笔记到 JSON 文件"""
with open(DATA_FILE, "w", encoding="utf-8") as f:
json.dump(notes, f, ensure_ascii=False, indent=2)
def add_note(title, content):
"""添加笔记"""
notes = load_notes()
notes.append({"title": title, "content": content})
save_notes(notes)
print(f"已添加笔记:{title}")
def list_notes():
"""列出所有笔记"""
notes = load_notes()
if not notes:
print("暂无笔记")
return
for i, note in enumerate(notes, 1):
print(f"{i}. {note['title']}")
add_note("学习 Python", "今天学了 JSON 模块")
add_note("购物清单", "买牛奶、面包、鸡蛋")
list_notes()
输出:
TEXT
📖 仅展示
暂无笔记
4. 处理复杂数据类型
默认情况下,json 模块只支持基本类型。自定义对象需要手动转换:
▶ 示例:自定义序列化
PYTHON
import json
from datetime import datetime
def custom_serializer(obj):
"""自定义序列化——处理 datetime 等类型"""
if isinstance(obj, datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
raise TypeError(f"无法序列化 {type(obj)}")
data = {
"name": "Alice",
"created_at": datetime.now(),
"active": True
}
json_str = json.dumps(data, default=custom_serializer, ensure_ascii=False, indent=2)
print(json_str)
输出:
TEXT
📖 仅展示
# 函数定义成功
5. 常见应用场景
- Web API 数据:调用外部 API 时,接收和发送 JSON 数据。
- 配置文件:用 JSON 格式存储配置,比 INI 更灵活。
- 数据持久化:把程序数据保存为 JSON 文件,比 CSV 更结构化(支持嵌套)。
- 数据交换:在不同语言、不同系统之间传递数据。
❓ 常见问题
Q JSON 文件比 CSV 文件好在哪里?
A JSON 支持嵌套结构(字典中套列表、列表中套字典),CSV 只能表示平面表格。JSON 自动保留数据类型(数字、布尔值、null),CSV 所有值都是字符串。JSON 可读性更好。缺点是 JSON 文件通常比 CSV 大。
Q
ensure_ascii=False 不设置会怎样?A 中文字符会被转义成
\uXXXX 格式。程序功能不受影响——json.loads() 会自动还原。但对于人类阅读来说,转义后的内容完全不可读。所以在需要手动查看 JSON 文件时,记得加 ensure_ascii=False。📖 小节
json.dumps()Python→JSON 字符串,json.loads()JSON 字符串→Pythonjson.dump()Python→JSON 文件,json.load()JSON 文件→Pythonensure_ascii=False保留中文,indent=2格式化输出- JSON 类型对应:
object→dict、array→list、number→int/float、null→None - 自定义类型需要提供
default序列化函数
📝 作业
-
基础题(难度⭐):创建一个字典,包含你的名字、年龄、三个爱好(列表),用
json.dumps()输出格式化的 JSON 字符串(保留中文、缩进 2 格)。 -
进阶题(难度⭐⭐):写两个函数:
save_contacts(contacts)和load_contacts(),把通讯录(列表嵌套字典)保存到contacts.json,程序启动时自动加载。每个联系人包含姓名、电话、邮箱。 -
挑战题(难度⭐⭐⭐):用 JSON 实现一个"简易数据导出器"。给定一个学生成绩的列表
students = [{"name": "Alice", "scores": {"语文": 85, "数学": 92}}],分别输出为:① 格式化的 JSON 文件;② 压缩成一行(无缩进)的 JSON 字符串;③ 带排序键(sort_keys=True)的 JSON 字符串。