Python怎么生成JSON:从基础到实践的全面指南
在Python开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其易读、易解析的特性,被广泛应用于Web开发、API接口、配置文件等场景,Python生成JSON数据的方法,是每个Python开发者的必备技能,本文将从基础语法出发,逐步到复杂场景处理,带你全面了解“Python怎么生成JSON”。
什么是JSON?为什么用Python生成JSON?
JSON是一种基于文本的数据格式,采用键值对(key-value pair)的结构,类似于Python中的字典(dict)和列表(list),它独立于语言,几乎所有编程语言都支持JSON的解析和生成,因此成为跨语言数据交换的“通用语言”。
Python生成JSON数据的常见场景包括:
- 将程序数据(如爬虫结果、数据库查询数据)保存为文件,供其他程序调用;
- 构建API接口时,将Python对象转换为JSON格式返回给前端;
- 配置文件的动态生成与存储。
Python生成JSON的核心模块:json
Python内置了json模块,专门用于处理JSON数据,该模块提供了两个核心函数:json.dumps()和json.dump(),分别用于将Python对象转换为JSON格式的字符串和写入文件。
json.dumps():将Python对象转为JSON字符串
dumps()是“dump string”的缩写,功能是将Python对象(如dict、list、str、int等)序列化为JSON格式的字符串。
基础语法
import json json_str = json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False)
常用参数说明
obj:要转换的Python对象(如dict、list);indent:缩进空格数,用于格式化输出(如indent=4,JSON字符串会自动换行和缩进,提升可读性);ensure_ascii:是否将非ASCII字符(如中文)转义为ASCII编码,默认为True(设置为False可保留原字符);sort_keys:是否对字典的键进行排序,默认为False。
示例:简单数据类型转换
import json
# 字典转JSON字符串
data = {"name": "张三", "age": 25, "is_student": False}
json_str = json.dumps(data)
print(json_str) # 输出: {"name": "\u5f20\u4e09", "age": 25, "is_student": false}
# 格式化输出(保留中文,缩进4空格)
json_str_formatted = json.dumps(data, ensure_ascii=False, indent=4)
print(json_str_formatted)
"""
输出:
{
"name": "张三",
"age": 25,
"is_student": false
}
"""
# 列表转JSON字符串
list_data = [1, 2, "hello", {"a": 1, "b": 2}]
json_list = json.dumps(list_data)
print(json_list) # 输出: [1, 2, "hello", {"a": 1, "b": 2}]
json.dump():将Python对象写入JSON文件
dump()是“dump file”的缩写,功能与dumps()类似,但直接将JSON字符串写入文件对象(需提前打开文件),避免了手动写入文件的步骤。
基础语法
import json
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(obj, f, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False)
示例:将字典写入JSON文件
import json
data = {
"users": [
{"name": "李四", "age": 30, "city": "北京"},
{"name": "王五", "age": 28, "city": "上海"}
],
"total": 2
}
# 写入文件(格式化,保留中文)
with open('users.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
print("JSON文件已生成:users.json")
执行后,users.json如下:
{
"users": [
{
"name": "李四",
"age": 30,
"city": "北京"
},
{
"name": "王五",
"age": 28,
"city": "上海"
}
],
"total": 2
}
复杂场景处理:自定义对象与异常处理
在实际开发中,我们可能需要将自定义类的对象、时间类型等复杂数据转换为JSON。json模块的默认序列化可能无法直接处理,需要借助default参数或自定义序列化方法。
处理自定义对象
假设有一个自定义类Person,直接使用json.dumps()会报错(TypeError),因为json模块不知道如何将Person对象转为字典。
解决方案1:通过default参数指定转换函数
import json
from datetime import datetime
class Person:
def __init__(self, name, age, birth_date):
self.name = name
self.age = age
self.birth_date = birth_date
# 自定义转换函数:将Person对象转为字典
def person_to_dict(person):
return {
"name": person.name,
"age": person.age,
"birth_date": person.birth_date.strftime("%Y-%m-%d") # 日期转字符串
}
p = Person("赵六", 35, datetime(1988, 5, 20))
# 使用default参数指定转换函数
json_str = json.dumps(p, default=person_to_dict, ensure_ascii=False, indent=4)
print(json_str)
"""
输出:
{
"name": "赵六",
"age": 35,
"birth_date": "1988-05-20"
}
"""
解决方案2:为自定义类添加to_dict()方法
import json
from datetime import datetime
class Person:
def __init__(self, name, age, birth_date):
self.name = name
self.age = age
self.birth_date = birth_date
def to_dict(self):
return {
"name": self.name,
"age": self.age,
"birth_date": self.birth_date.strftime("%Y-%m-%d")
}
p = Person("赵六", 35, datetime(1988, 5, 20))
# 直接调用to_dict()方法
json_str = json.dumps(p.to_dict(), ensure_ascii=False, indent=4)
print(json_str)
# 输出同上
处理时间类型(datetime)
datetime对象是Python常见的数据类型,但无法直接序列化为JSON,通常需要将其转换为字符串或时间戳。
示例:日期时间转字符串
import json
from datetime import datetime
data = {
"event": "Python讲座",
"time": datetime.now()
}
# 自定义转换函数
def datetime_to_str(obj):
if isinstance(obj, datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
json_str = json.dumps(data, default=datetime_to_str, ensure_ascii=False)
print(json_str)
# 输出: {"event": "Python讲座", "time": "2023-10-01 14:30:00"}
处理异常情况
在序列化过程中,可能会遇到TypeError(如对象不可序列化),此时可以通过try-except捕获异常,或使用json.JSONEncoder自定义编码器。
示例:自定义编码器处理不可序列化对象
import json
from datetime import datetime
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
# 其他自定义类型处理
return super().default(obj)
data = {
"event": "Python讲座",
"time": datetime.now(),
"extra": lambda x: x * 2 # 不可序列化的lambda函数
}
try:
json_str = json.dumps(data, cls=CustomEncoder, ensure_ascii=False)
print(json_str)
except TypeError as e:
print(f"序列化失败: {e}")
# 移除不可序列化的字段后重试
data.pop("extra")
json_str = json.dumps(data, cls=CustomEncoder, ensure_ascii=False)
print("修正后的JSON:", json_str)


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