Python JSON模块详解:从入门到高级应用
一、初识JSON与Python的json模块
1. 什么是JSON?
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,具有以下特点:
- 人类可读的文本格式
- 独立于编程语言(Python/Java/JavaScript等都能处理)
- 结构清晰:键值对集合(对象)和有序值列表(数组)
示例比较XML与JSON:
<!-- XML格式 -->
<user>
<name>张三</name>
<age>25</age>
<skills>
<skill>Python</skill>
<skill>Java</skill>
</skills>
</user>
// JSON格式
{
"name": "张三",
"age": 25,
"skills": ["Python", "Java"]
}
2. 为什么需要json模块?
- 网络传输:Web API数据交换(如微信接口)
- 配置文件:存储程序设置信息
- 数据持久化:简单数据存储
- 跨语言协作:与JavaScript/Java等其他语言交互
3. 基础数据类型对照表
Python类型 | JSON类型 |
---|---|
dict |
object |
list |
array |
str |
string |
int/float |
number |
True/False |
true/false |
None |
null |
二、基础操作步步学
1. 模块导入与基本方法
import json
# 核心方法清单
print([func for func in dir(json) if not func.startswith('_')])
# 输出:['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', 'dump', 'dumps', 'load', 'loads']
2. 序列化操作(Python → JSON)
# 创建示例数据
data = {
"project": "天气预报系统",
"version": 1.2,
"authors": ["张三", "李四"],
"stable": True,
"config": None
}
# 基本序列化
json_str = json.dumps(data)
print(type(json_str)) # <class 'str'>
print(json_str)
# {"project": "\u5929\u6c14\u9884\u62a5\u7cfb\u7edf", "version": 1.2, ...}
# 解决中文乱码问题
json_str_chinese = json.dumps(data, ensure_ascii=False)
print(json_str_chinese)
# {"project": "天气预报系统", ...}
3. 反序列化操作(JSON → Python)
# 基本反序列化
restored_data = json.loads(json_str_chinese)
print(type(restored_data)) # <class 'dict'>
print(restored_data["authors"]) # ['张三', '李四']
# 验证数据一致性
assert restored_data == data # 无报错说明数据一致
4. 文件读写操作
# 写入JSON文件
with open("config.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
# 读取JSON文件
with open("config.json", "r", encoding="utf-8") as f:
file_data = json.load(f)
print(file_data["project"]) # 天气预报系统
三、参数详解与实用技巧
1. dumps常用参数演示
# 美观格式化输出
print(json.dumps(data, indent=4, ensure_ascii=False))
"""
{
"project": "天气预报系统",
"version": 1.2,
"authors": [
"张三",
"李四"
],
"stable": true,
"config": null
}
"""
# 键排序与紧凑格式
print(json.dumps(data, sort_keys=True, separators=(',', ':')))
# {"authors":["张三","李四"],"config":null,"project":"天气预报系统","stable":true,"version":1.2}
2. 特殊数据类型处理
# 处理日期时间
from datetime import datetime
event = {
"title": "项目启动会",
"time": datetime(2023, 8, 25, 14, 30)
}
# 直接序列化会报错!
# json.dumps(event) # TypeError: Object of type datetime is not JSON serializable
# 自定义处理函数
def datetime_handler(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError("无法序列化的类型")
print(json.dumps(event, default=datetime_handler, ensure_ascii=False))
# {"title": "项目启动会", "time": "2023-08-25T14:30:00"}
四、面向对象编程实战
1. 自定义类序列化
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __repr__(self):
return f"<Student {self.name} [{self.score}]>"
# 创建实例
stu = Student("王五", 95)
# 方案1:自定义转换函数
def student_encoder(obj):
if isinstance(obj, Student):
return {"name": obj.name, "score": obj.score}
raise TypeError
json_str = json.dumps(stu, default=student_encoder, ensure_ascii=False)
print(json_str) # {"name": "王五", "score": 95}
# 方案2:继承JSONEncoder
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Student):
return {"name": obj.name, "score": obj.score}
return super().default(obj)
print(json.dumps(stu, cls=MyEncoder)) # {"name": "王五", "score": 95}
2. 自定义类反序列化
# 反序列化处理函数
def student_decoder(dct):
if "name" in dct and "score" in dct:
return Student(dct["name"], dct["score"])
return dct
# 反序列化操作
restored_stu = json.loads(json_str, object_hook=student_decoder)
print(type(restored_stu)) # <class '__main__.Student'>
print(restored_stu) # <Student 王五 >
五、错误处理与调试技巧
1. 常见错误类型
# 格式错误示例
invalid_json = '{"name": "张三", "age": 25,}'
try:
json.loads(invalid_json)
except json.JSONDecodeError as e:
print(f"错误位置:第{e.lineno}行第{e.colno}列")
print(f"错误详情:{e.msg}")
# 错误位置:第1行第25列
# 错误详情:Expecting property name enclosed in double quotes
2. 调试技巧
# 使用pprint查看数据结构
from pprint import pprint
complex_data = {
"users": [
{"name": "张三", "contacts": {"email": "zhangsan@example.com", "phone": "13800138000"}},
{"name": "李四", "contacts": {"email": "lisi@example.com"}}
]
}
pprint(json.loads(json.dumps(complex_data)))
"""
{'users': [{'contacts': {'email': 'zhangsan@example.com', 'phone': '13800138000'},
'name': '张三'},
{'contacts': {'email': 'lisi@example.com'}, 'name': '李四'}]}
"""
六、综合应用案例
1. 模拟Web API交互
import requests # 需先安装:pip install requests
# 获取公开API数据
response = requests.get("https://api.github.com/users/octocat")
api_data = response.json()
# 提取关键信息
processed = {
"username": api_data["login"],
"name": api_data["name"],
"followers": api_data["followers"]
}
# 保存到本地
with open("github_user.json", "w") as f:
json.dump(processed, f, indent=2)
print(open("github_user.json").read())
"""
{
"username": "octocat",
"name": "The Octocat",
"followers": 7940
}
"""
七、最佳实践与注意事项
安全警示
- 不要反序列化不可信来源的JSON数据
- 使用
object_hook
时验证数据完整性
性能优化
- 处理大文件时使用
json.load()
替代json.loads()
- 设置合理的
indent
参数(生产环境通常不使用)
编码规范
- 统一使用UTF-8编码
- 保持键名的一致性(如全小写加下划线)
扩展建议
- 使用
simplejson
库处理更复杂的需求 - 结合
jsonschema
验证JSON格式
# 扩展:使用类型注解(Python 3.9+)
from typing import TypedDict
class UserData(TypedDict):
name: str
age: int
def validate_user(data: UserData):
if not isinstance(data["age"], int):
raise ValueError("年龄必须是整数")
user = json.loads('{"name": "张三", "age": 25}')
validate_user(user)
通过本文的学习,你已经掌握了JSON模块的核心用法。记住:多动手实践、遇到错误仔细阅读提示信息、善用Python的文档资源(help(json.JSONEncoder)
),你就能在项目中游刃有余地处理JSON数据啦!