当前位置: 代码网 > it编程>前端脚本>Python > Python数据类转换为JSON的常用方法总结

Python数据类转换为JSON的常用方法总结

2026年01月20日 Python 我要评论
python 标准库的json模块默认无法直接序列化自定义的dataclass实例(会报object of type xxx is not json serializable),核心原因是json只支

python 标准库的json模块默认无法直接序列化自定义的dataclass实例(会报object of type xxx is not json serializable),核心原因是json只支持基础类型(str/int/list/dict 等)。下面我会从基础到进阶给出 4 种优雅的转换方法,覆盖简单场景到生产级复杂场景,你可根据需求选择。

前置准备:定义测试数据类

先定义一个典型的嵌套数据类,作为后续转换的示例:

from dataclasses import dataclass, asdict
import json
from datetime import datetime  # 包含非基础类型,模拟真实场景

# 嵌套子数据类
@dataclass
class address:
    province: str
    city: str
    detail: str = ""  # 可选字段

# 主数据类
@dataclass
class user:
    id: int
    name: str
    age: int
    register_time: datetime  # 非json原生类型
    address: address  # 嵌套数据类
    tags: list[str] = none  # 可选列表字段

# 创建测试实例
test_user = user(
    id=1001,
    name="张三",
    age=28,
    register_time=datetime(2026, 1, 19, 10, 30),
    address=address(province="浙江省", city="杭州市", detail="西湖区xx路"),
    tags=["vip", "新用户"]
)

方法 1:基础版 -dataclasses.asdict手动转换(简单场景)

这是最基础的优雅方式,利用dataclasses内置的asdict方法将数据类转成字典,再用json.dumps序列化。

代码实现:

# 步骤1:将dataclass转成普通字典
user_dict = asdict(test_user)
# 步骤2:处理非json原生类型(如datetime)
user_dict["register_time"] = user_dict["register_time"].isoformat()

# 步骤3:序列化为json字符串
user_json = json.dumps(user_dict, ensure_ascii=false, indent=2)
print(user_json)

输出结果:

{
  "id": 1001,
  "name": "张三",
  "age": 28,
  "register_time": "2026-01-19t10:30:00",
  "address": {
    "province": "浙江省",
    "city": "杭州市",
    "detail": "西湖区xx路"
  },
  "tags": ["vip", "新用户"]
}

关键解释:

  • asdict(test_user):核心函数,将数据类实例递归转换为普通字典(嵌套的address也会被转成字典);
  • ensure_ascii=false:保留中文等非 ascii 字符,避免转成\uxxxx编码;
  • indent=2:格式化输出,提升可读性;
  • 需手动处理datetime等非 json 原生类型(json 仅支持字符串 / 数字 / 布尔 / 列表 / 字典 /null)。

方法 2:进阶版 - 自定义jsonencoder(通用可扩展)

如果有多个数据类需要转换,手动处理非基础类型会很繁琐,推荐自定义jsonencoder,实现统一的序列化规则

代码实现:

class dataclassjsonencoder(json.jsonencoder):
    """自定义json编码器,支持dataclass和常见非基础类型"""
    def default(self, obj):
        # 第一步:处理dataclass实例
        if hasattr(obj, "__dataclass_fields__"):  # 判断是否是dataclass
            return asdict(obj)
        # 第二步:处理datetime类型
        if isinstance(obj, datetime):
            return obj.isoformat()
        # 第三步:其他类型交给父类处理(会抛出标准异常)
        return super().default(obj)

# 直接使用自定义编码器序列化
user_json = json.dumps(
    test_user,
    cls=dataclassjsonencoder,  # 指定自定义编码器
    ensure_ascii=false,
    indent=2
)
print(user_json)

关键解释:

  • 继承json.jsonencoder并重写default方法:这是json模块扩展序列化规则的标准方式;
  • __dataclass_fields__:dataclass 实例的内置属性,用于判断是否为数据类;
  • 可扩展:如需支持date/uuid等类型,只需在default方法中新增isinstance判断即可;
  • 无需手动转字典,直接序列化数据类实例,代码更简洁。

方法 3:优化版 - 封装成工具函数(复用性拉满)

将转换逻辑封装成工具函数,一键调用,适合项目中多处使用的场景:

def dataclass_to_json(obj, indent=2):
    """
    数据类转json字符串的工具函数
    :param obj: 数据类实例(支持嵌套)
    :param indent: 格式化缩进,none表示紧凑输出
    :return: json字符串
    """
    return json.dumps(
        obj,
        cls=dataclassjsonencoder,
        ensure_ascii=false,
        indent=indent
    )

# 调用示例(一行搞定)
user_json = dataclass_to_json(test_user)
print(user_json)

方法 4:高级版 - 使用pydantic(生产环境推荐)

如果你的场景需要数据验证 + 优雅序列化,推荐直接使用pydantic(python 生态中最主流的数据验证库),它的basemodel比原生dataclass更强大,且原生支持 json 转换。

前置依赖:

pip install pydantic

代码实现:

from pydantic import basemodel
from datetime import datetime

# 替换原生dataclass为pydantic.basemodel
class address(basemodel):
    province: str
    city: str
    detail: str = ""

class user(basemodel):
    id: int
    name: str
    age: int
    register_time: datetime
    address: address
    tags: list[str] = none

    # 可选:自定义json序列化配置(如datetime格式)
    class config:
        json_encoders = {
            datetime: lambda v: v.strftime("%y-%m-%d %h:%m:%s")  # 自定义时间格式
        }

# 创建实例(pydantic会自动验证字段类型)
test_user = user(
    id=1001,
    name="张三",
    age=28,
    register_time=datetime(2026, 1, 19, 10, 30),
    address=address(province="浙江省", city="杭州市", detail="西湖区xx路"),
    tags=["vip", "新用户"]
)

# 原生支持json转换(一行搞定)
user_json = test_user.json(ensure_ascii=false, indent=2)
print(user_json)

输出结果(时间格式自定义后):

{
  "id": 1001,
  "name": "张三",
  "age": 28,
  "register_time": "2026-01-19 10:30:00",
  "address": {
    "province": "浙江省",
    "city": "杭州市",
    "detail": "西湖区xx路"
  },
  "tags": ["vip", "新用户"]
}

关键优势:

  • 原生支持json()方法:无需手动写编码器,开箱即用;
  • 自动数据验证:创建实例时会校验字段类型(如age传字符串会直接报错);
  • 灵活配置:通过config.json_encoders自定义非基础类型的序列化规则;
  • 支持嵌套、可选字段、默认值等,完全兼容原生 dataclass 的用法,且功能更强。

总结

  1. 简单场景:用dataclasses.asdict + json.dumps,手动处理非基础类型,快速实现;
  2. 通用场景:自定义jsonencoder,统一管理序列化规则,适合多个数据类的项目;
  3. 生产环境:优先使用pydantic.basemodel,兼顾数据验证和优雅序列化,减少冗余代码;
  4. 核心原则:避免手动拼接字典,利用内置工具 / 成熟库实现转换,保证代码的可维护性和扩展性。

以上就是python数据类转换为json的常用方法总结的详细内容,更多关于python数据类转json的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com