Python JSON模块完全指南:从入门到进阶
一、JSON基础认知
1. JSON是什么?
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,具有以下核心特征:
- 人类可读的文本格式
- 语言无关的通用数据格式
- 层次化的键值对结构
- 支持嵌套数据结构
- 扩展名通常为
.json
2. 为什么选择JSON?
- 跨平台性:几乎所有编程语言都支持
- 简洁性:相比XML更简洁,数据体积更小
- 易解析:结构化数据便于程序处理
- 扩展性:支持嵌套结构表达复杂数据关系
3. Python与JSON的完美结合
Python通过内置json
模块提供:
- 序列化(Serialization):Python对象 → JSON字符串
- 反序列化(Deserialization):JSON字符串 → Python对象
- 支持自定义数据类型处理
- 灵活的可视化输出控制
二、核心方法解析
1. 序列化方法
方法 | 参数 | 返回值 | 使用场景 |
---|---|---|---|
dumps() | obj, indent=None | 字符串 | 内存数据转换 |
dump() | obj, fp, indent | None | 文件写入 |
示例代码:
import jsondata = {"project": "Python JSON指南","version": 1.0,"keywords": ["数据交换", "序列化", "配置"],"private": False
}# 内存转换
json_str = json.dumps(data, indent=2, ensure_ascii=False)# 文件存储
with open("config.json", "w", encoding="utf-8") as f:json.dump(data, f, indent=4)
2. 反序列化方法
方法 | 参数 | 返回值 | 使用场景 |
---|---|---|---|
loads() | s | 对象 | 字符串解析 |
load() | fp | 对象 | 文件读取 |
示例代码:
# 从字符串解析
restored_data = json.loads('{"name": "Alice", "age": 30}')# 从文件读取
with open("data.json", "r", encoding="utf-8") as f:file_data = json.load(f)
3. 数据类型对照表
Python类型 | JSON类型 | 说明 |
---|---|---|
dict | object | 字典转为JSON对象 |
list/tuple | array | 列表/元组转为数组 |
str | string | Unicode字符串 |
int/float | number | 整数/浮点数 |
True/False | true/false | 布尔值小写 |
None | null | 空值表示 |
三、进阶使用技巧
1. 自定义对象序列化
from datetime import datetime
import jsonclass User:def __init__(self, name, join_date):self.name = nameself.join_date = join_dateclass CustomEncoder(json.JSONEncoder):def default(self, obj):if isinstance(obj, User):return {"name": obj.name,"join_date": obj.join_date.strftime("%Y-%m-%d")}elif isinstance(obj, datetime):return obj.isoformat()return super().default(obj)user = User("王小明", datetime.now())
print(json.dumps(user, cls=CustomEncoder, ensure_ascii=False))
2. 复杂JSON处理
处理嵌套结构:
data = {"employees": [{"name": "张三", "projects": ["A", "B"]},{"name": "李四", "projects": ["C"]}]
}# 查询第一个员工的第二个项目
json_str = json.dumps(data)
parsed = json.loads(json_str)
print(parsed["employees"][0]["projects"][1]) # 输出:B
3. 性能优化技巧
- 禁用ASCII转换:
ensure_ascii=False
- 压缩输出:
separators=(',', ':')
- 使用C扩展:
ujson
或orjson
第三方库 - 对象钩子处理:
object_hook
参数
# 高性能序列化
json.dumps(data, separators=(',', ':'), ensure_ascii=False)# 使用ujson(需安装)
import ujson
ujson.dumps(data)
四、安全与最佳实践
1. 安全准则
- 永远不要反序列化不可信来源的JSON
- 使用
json.JSONDecodeError
捕获解析错误 - 对输入数据进行合法性验证
- 谨慎处理
eval()
和ast.literal_eval()
2. 错误处理示范
try:with open("data.json", "r") as f:data = json.load(f)
except json.JSONDecodeError as e:print(f"JSON解析错误: {e}")
except FileNotFoundError:print("文件不存在")
except Exception as e:print(f"未知错误: {e}")
3. 格式规范建议
- 开发环境使用
indent=4
增强可读性 - 生产环境去掉缩进减少体积
- 统一使用UTF-8编码
- 对中文禁用ASCII转换
- 使用JSON Schema验证数据结构
五、常见问题解决方案
1. 中文乱码问题
# 正确写法
json.dumps(data, ensure_ascii=False, indent=2)# 文件操作
with open("data.json", "w", encoding="utf-8") as f:json.dump(data, f, ensure_ascii=False)
2. 日期时间处理
扩展编码器:
from datetime import dateclass EnhancedEncoder(json.JSONEncoder):def default(self, obj):if isinstance(obj, (datetime, date)):return obj.isoformat()return super().default(obj)
3. 处理特殊值
# 转换NaN和Infinity
data = {"temperature": float('inf'),"ratio": float('nan')
}json_str = json.dumps(data, allow_nan=False) # 会引发ValueError
六、扩展应用场景
1. API交互
import requests# 发送JSON数据
response = requests.post('https://api.example.com/data',json={"query": "Python"},headers={'Content-Type': 'application/json'}
)# 解析响应
result = response.json()
2. 配置文件管理
# 读取配置
with open("config.json") as f:config = json.load(f)# 更新配置
config["timeout"] = 30
with open("config.json", "w") as f:json.dump(config, f, indent=4)
3. 数据持久化
class Database:def __init__(self, filename):self.filename = filenamedef save(self, data):with open(self.filename, "w") as f:json.dump(data, f)def load(self):try:with open(self.filename) as f:return json.load(f)except FileNotFoundError:return {}
七、总结与推荐
学习建议
- 掌握基础数据类型转换
- 熟练使用四个核心方法
- 理解编码/解码过程
- 实践自定义类型处理
- 建立数据验证机制
推荐工具
- JSONLint:在线JSON验证工具
- Postman:API测试工具
- VS Code:自带JSON语法高亮和验证
- jq:命令行JSON处理工具
扩展阅读
- JSON官方文档
- Python JSON模块官方文档
- JSON Schema规范