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 datetimeevent = {"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 = nameself.score = scoredef __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 TypeErrorjson_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 pprintcomplex_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 TypedDictclass UserData(TypedDict):name: strage: intdef 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数据啦!