0

0

json.dumps() 如何优雅处理 datetime/decimal/自定义类对象

冷漠man

冷漠man

发布时间:2026-01-21 09:17:31

|

419人浏览过

|

来源于php中文网

原创

json.dumps() 默认不支持 datetime、Decimal 和自定义类,需通过 default 参数或自定义 JSONEncoder 实现序列化:datetime/date 转 ISO 字符串,Decimal 推荐转 str 保精度,自定义类优先用 to_dict() 方法。

json.dumps() 如何优雅处理 datetime/decimal/自定义类对象

直接用 json.dumps() 处理 datetimeDecimal 或自定义类对象会报错,因为 JSON 标准只支持 strintfloatboolNonelistdict 这几种类型。解决的关键是提供一个能识别并转换这些“不兼容类型”的 default 回调函数

用 default 参数统一转换特殊类型

这是最常用也最灵活的方式。你写一个函数,判断对象类型,返回 JSON 可序列化的等价表示:

  • datetime.date / datetime.datetime → 转成 ISO 格式字符串(如 "2024-05-20""2024-05-20T14:30:00.123"
  • decimal.Decimal → 转成 float(注意精度损失)或 str(推荐,保留精度)
  • 自定义类 → 返回其 __dict__,或显式定义字段字典(更可控)

示例:

import json
from datetime import datetime, date
from decimal import Decimal

def json_serializer(obj): if isinstance(obj, (datetime, date)): return obj.isoformat() if isinstance(obj, Decimal): return str(obj) # 避免 float 精度问题 if hasattr(obj, 'dict'): return obj.dict raise TypeError(f"Object of type {type(obj)} is not JSON serializable")

data = { "time": datetime.now(), "price": Decimal("99.99"), "user": type('User', (), {"name": "Alice", "age": 30})() }

json.dumps(data, default=json_serializer, ensure_ascii=False)

为自定义类实现 to_dict() 方法更清晰

比起依赖 __dict__(可能包含私有属性、方法、循环引用),在类里明确定义 to_dict() 更安全、可维护性更高:

MedPeer科研绘图
MedPeer科研绘图

生物医学领域的专业绘图解决方案,告别复杂绘图,专注科研创新

下载
class Product:
    def __init__(self, name, price, created_at):
        self.name = name
        self.price = price
        self.created_at = created_at
def to_dict(self):
    return {
        "name": self.name,
        "price": str(self.price),
        "created_at": self.created_at.isoformat() if self.created_at else None
    }

在 serializer 中调用

def json_serializer(obj): if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): return obj.to_dict()

其他类型处理...

用 cls 参数继承 JSONEncoder 更适合项目级复用

如果多个地方都需要相同规则,继承 json.JSONEncoder 并重写 default 方法,代码更结构化,也方便统一配置(比如全局控制日期格式):

class CustomJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime("%Y-%m-%d %H:%M:%S")
        if isinstance(obj, date):
            return obj.isoformat()
        if isinstance(obj, Decimal):
            return float(obj) if obj.as_tuple().exponent >= 0 else str(obj)
        if hasattr(obj, 'to_dict'):
            return obj.to_dict()
        return super().default(obj)

json.dumps(data, cls=CustomJSONEncoder, ensure_ascii=False)

小提醒:避免踩坑

别用 str(obj) 一锅端 —— 对于 datetime 是 OK 的,但对 Decimal('1.00') 得到 "1.00" 还行,而对自定义类可能输出 "<__main__.user object at>",毫无意义。
慎用 float(Decimal) —— 小数位数多时会丢失精度,金融场景务必用 str()
注意嵌套对象 —— 如果自定义类属性里还有 datetime 或 Decimal,确保 to_dict()default 递归处理它们。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

414

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

533

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

310

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

75

2025.09.10

css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

569

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

99

2025.10.23

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

755

2023.08.22

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

258

2023.08.03

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

19

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.4万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号