Python中使用JSON进行数据存取的完整指南
Python中使用JSON进行数据存取的完整指南
在Python开发中,JSON(JavaScript Object Notation)作为一种轻量级、易读的数据交换格式,被广泛应用于配置文件、API数据交互、数据存储等场景,Python内置了json模块,提供了简单高效的方法实现JSON数据的序列化(将Python对象转为JSON字符串)和反序列化(将JSON字符串转为Python对象),本文将详细介绍如何使用Python的json模块进行数据的存取操作,涵盖基础操作、文件读写、异常处理及进阶技巧。
JSON与Python对象的对应关系
JSON数据格式与Python内置数据类型存在天然对应关系,理解这种对应是正确存取数据的前提:
| JSON类型 | Python类型 |
|---|---|
| 对象() | 字典(dict) |
数组([]) |
列表(list) |
| 字符串() | 字符串(str) |
| 数字(整数/浮点) | 整数(int)/浮点数(float) |
布尔值(true/false) |
布尔值(True/False) |
空值(null) |
None |
JSON数据写入:将Python对象转为JSON并存储
JSON数据的“存”主要指将Python对象序列化为JSON字符串,并保存到文件或变量中,核心方法是json.dump()(写入文件)和json.dumps()(转为字符串)。
使用json.dumps()将Python对象转为JSON字符串
json.dumps()(dumps = dump string)用于将Python对象序列化为JSON格式的字符串,适合在内存中处理数据。
import json
# 定义Python字典
data = {
"name": "张三",
"age": 25,
"is_student": False,
"courses": ["数学", "Python"],
"info": None
}
# 序列化为JSON字符串
json_str = json.dumps(data, ensure_ascii=False, indent=4)
print("JSON字符串:")
print(json_str)
参数说明:
ensure_ascii=False:允许非ASCII字符(如中文)直接输出,避免转义为\u格式。indent=4:格式化输出,指定缩进空格数,提升可读性(默认不缩进,输出为一行)。
输出结果:
{
"name": "张三",
"age": 25,
"is_student": false,
"courses": [
"数学",
"Python"
],
"info": null
}
使用json.dump()将Python对象写入文件
json.dump()(dump = dump file)直接将Python对象序列化并写入文件,避免手动拼接字符串和文件操作的麻烦。
import json
# 同样的Python字典数据
data = {
"name": "李四",
"age": 30,
"skills": ["Java", "SQL"],
"contact": {
"email": "lisi@example.com",
"phone": "13800138000"
}
}
# 写入JSON文件(UTF-8编码)
with open("user.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
print("数据已写入 user.json 文件")
user.json):**
{
"name": "李四",
"age": 30,
"skills": [
"Java",
"SQL"
],
"contact": {
"email": "lisi@example.com",
"phone": "13800138000"
}
}
关键点:
- 使用
with open()确保文件自动关闭,避免资源泄漏。 - 指定
encoding="utf-8"避免中文等字符乱码。
JSON数据读取:将JSON文件或字符串转为Python对象
JSON数据的“取”指从文件或字符串中读取JSON数据,并反序列化为Python对象,核心方法是json.load()(从文件读取)和json.loads()(从字符串读取)。
使用json.loads()将JSON字符串转为Python对象
json.loads()(loads = load string)用于解析JSON字符串,返回对应的Python对象。
import json
# JSON字符串
json_str = '{"name": "王五", "age": 28, "hobbies": ["阅读", "游泳"]}'
# 反序列化为Python字典
python_obj = json.loads(json_str)
print("Python对象类型:", type(python_obj))
print("姓名:", python_obj["name"])
print("爱好:", python_obj["hobbies"])
输出结果:
Python对象类型: <class 'dict'>
姓名: 王五
爱好: ['阅读', '游泳']
使用json.load()从JSON文件读取数据
json.load()(load = load file)直接从文件对象中读取JSON数据并反序列化为Python对象。
import json
# 从之前写入的 user.json 文件读取
with open("user.json", "r", encoding="utf-8") as f:
data = json.load(f)
print("从文件读取的Python对象:")
print(data)
print("邮箱:", data["contact"]["email"])
输出结果:
从文件读取的Python对象:
{'name': '李四', 'age': 30, 'skills': ['Java', 'SQL'], 'contact': {'email': 'lisi@example.com', 'phone': '13800138000'}}
邮箱: lisi@example.com
异常处理:增强JSON操作的健壮性
JSON操作中可能因数据格式错误、文件问题等引发异常,需通过try-except捕获并处理:
import json
# 示例1:JSON字符串格式错误
invalid_json_str = "{'name': '赵六', 'age': 22}" # 单引号不符合JSON规范
try:
data = json.loads(invalid_json_str)
except json.JSONDecodeError as e:
print(f"JSON解析错误:{e}") # 输出:JSON解析错误:Expecting property name enclosed in double quotes
# 示例2:文件不存在或读取错误
try:
with open("nonexistent.json", "r", encoding="utf-8") as f:
data = json.load(f)
except FileNotFoundError:
print("错误:文件不存在")
except json.JSONDecodeError:
print("错误:文件内容不是有效的JSON格式")
常见异常:
json.JSONDecodeError:JSON字符串格式错误(如单引号、缺少逗号等)。FileNotFoundError:文件不存在或路径错误。UnicodeDecodeError:文件编码与指定编码不一致(如文件是GBK却指定UTF-8)。
进阶技巧:处理复杂对象与自定义序列化
Python的json模块默认支持基本数据类型,但遇到datetime、自定义类等复杂对象时会报错,需通过自定义序列化方法扩展支持。
处理datetime对象
import json
from datetime import datetime
data = {
"event": "会议",
"time": datetime.now(), # datetime对象无法直接序列化
"participants": ["张三", "李四"]
}
# 自定义序列化函数
def datetime_handler(obj):
if isinstance(obj, datetime):
return obj.isoformat() # 转为ISO格式字符串
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
# 使用default参数指定自定义函数
json_str = json.dumps(data, default=datetime_handler, ensure_ascii=False)
print("包含datetime的JSON字符串:")
print(json_str)
# 反序列化时需手动转换回datetime
parsed_data = json.loads(json_str)
parsed_data["time"] = datetime.fromisoformat(parsed_data["time"])
print("反序列化后的datetime对象:", parsed_data["time"])
输出结果:
包含datetime的JSON字符串:
{"event": "会议", "time": "2023-10-01 14:30:00", "participants": ["张三", "李四"]}
反序列化后的datetime对象: 2023-10-01 14:30:00
自定义类的序列化
import json
class User:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"User(name={self.name}, age={self.age})"
# 自定义序列化函数
def user_serializer(obj):
if isinstance(obj, User):
return {"__user__": True, "name": obj.name, "age":


还没有评论,来说两句吧...