《详解Python中JSON的基本使用方法》
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,因其易读性、结构简洁和跨语言支持,被广泛应用于前后端数据交互、配置文件存储等场景。Python通过内置的json
模块提供了对JSON的完整支持,包括序列化(将Python对象转为JSON字符串)和反序列化(将JSON字符串转为Python对象)。本文将详细介绍JSON在Python中的核心用法,涵盖基础操作、高级技巧及常见问题解决方案。
一、JSON与Python数据类型的对应关系
在操作JSON前,需明确其与Python数据类型的映射关系:
JSON类型 | Python类型 |
---|---|
对象(Object) | 字典(dict) |
数组(Array) | 列表(list) |
字符串(String) | 字符串(str) |
数字(Number) | 整数(int)/浮点数(float) |
布尔值(true/false) | 布尔值(True/False) |
空值(null) | None |
二、核心方法详解
1. 序列化:Python对象 → JSON字符串
使用json.dumps()
将Python对象转为JSON格式字符串,或通过json.dump()
直接写入文件。
import json
data = {
"name": "Alice",
"age": 30,
"skills": ["Python", "JSON"],
"is_active": True
}
# 转为JSON字符串
json_str = json.dumps(data, indent=4) # indent参数美化输出
print(json_str)
# 写入JSON文件
with open("data.json", "w") as f:
json.dump(data, f)
参数说明:
-
indent
:缩进空格数,用于美化输出 -
sort_keys
:是否按键名排序(默认False) -
ensure_ascii
:是否转义非ASCII字符(默认True,设为False可保留中文)
2. 反序列化:JSON字符串 → Python对象
使用json.loads()
解析JSON字符串,或通过json.load()
从文件读取。
import json
json_str = '{"name": "Bob", "age": 25, "city": "北京"}'
# 解析JSON字符串
python_dict = json.loads(json_str)
print(python_dict["name"]) # 输出: Bob
# 从文件读取
with open("data.json", "r") as f:
loaded_data = json.load(f)
3. 处理复杂数据类型
JSON默认不支持Python的datetime
、set
等类型,需通过自定义函数实现转换。
import json
from datetime import datetime
# 自定义序列化函数
def default_serializer(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError("Type not serializable")
data = {
"event": "会议",
"time": datetime.now()
}
json_str = json.dumps(data, default=default_serializer)
print(json_str)
反序列化时,可通过object_hook
参数还原自定义类型:
def as_datetime(dct):
if "__datetime__" in dct:
return datetime.fromisoformat(dct["__datetime__"])
return dct
json_str = '{"__datetime__": "2023-01-01T12:00:00"}'
obj = json.loads(json_str, object_hook=as_datetime)
三、高级应用场景
1. 压缩JSON输出
通过移除空白符减少数据体积:
compact_json = json.dumps(data, separators=(",", ":"))
2. 处理JSONP请求
为跨域请求添加回调函数包装:
def jsonp_response(data, callback):
return f"{callback}({json.dumps(data)})"
print(jsonp_response({"status": "ok"}, "handleResponse"))
3. 性能优化
对于大数据量,使用orjson
等第三方库提升速度:
# 安装: pip install orjson
import orjson
data = {"key": "value" * 1000}
json_bytes = orjson.dumps(data) # 返回bytes类型
四、常见问题与解决方案
1. 中文乱码问题
设置ensure_ascii=False
保留非ASCII字符:
json.dumps({"城市": "上海"}, ensure_ascii=False)
2. 循环引用错误
JSON不支持对象间的循环引用,需手动处理或使用pickle
替代:
class Node:
def __init__(self, value):
self.value = value
self.children = []
# 错误示例(会引发TypeError)
# root = Node(1)
# child = Node(2)
# root.children.append(child)
# child.children.append(root)
# json.dumps(root.__dict__)
3. 大数精度丢失
JSON规范中数字为IEEE 754双精度浮点数,超大整数可能丢失精度。解决方案:
- 转为字符串传输
- 使用
decimal.Decimal
类型
import json
from decimal import Decimal
data = {"big_num": Decimal("12345678901234567890")}
def decimal_serializer(obj):
if isinstance(obj, Decimal):
return str(obj)
raise TypeError
print(json.dumps(data, default=decimal_serializer))
五、最佳实践建议
-
数据验证:反序列化前验证JSON结构,可使用
jsonschema
库 -
异常处理:捕获
json.JSONDecodeError
处理无效输入 - 安全考虑:避免直接反序列化不可信来源的JSON(可能存在代码注入风险)
- 性能测试:对高频操作进行基准测试,选择最优实现方式
六、完整示例:配置文件管理
以下示例展示如何使用JSON管理应用程序配置:
import json
import os
CONFIG_FILE = "app_config.json"
def load_config():
try:
with open(CONFIG_FILE, "r") as f:
return json.load(f)
except FileNotFoundError:
return {"theme": "light", "language": "en"}
def save_config(config):
with open(CONFIG_FILE, "w") as f:
json.dump(config, f, indent=4)
# 使用示例
config = load_config()
config["language"] = "zh-CN"
save_config(config)
七、与其他数据格式对比
特性 | JSON | XML | YAML |
---|---|---|---|
可读性 | ★★★★ | ★★ | ★★★★★ |
解析速度 | ★★★★★ | ★★ | ★★★ |
数据类型支持 | 基础类型 | 丰富 | 丰富 |
适用场景 | Web API | 企业集成 | 配置文件 |
关键词:Python、JSON、序列化、反序列化、数据交换、json模块、JSONDecodeError、orjson、JSONP、数据类型映射
简介:本文全面介绍了Python中JSON模块的使用方法,涵盖基础序列化/反序列化操作、复杂数据类型处理、性能优化技巧及常见问题解决方案,通过代码示例和对比分析帮助开发者高效处理JSON数据。