pythonjson序列化_dumps与loads处理字典、类与日期时间技巧

发布时间 - 2026-02-02 00:00:00    点击率:
json.dumps序列化datetime需用default参数转isoformat,反序列化需object_hook手动还原;避免__dict__陷阱,推荐to_dict方法;中文输出须设ensure_ascii=False和indent。

json.dumps 序列化字典时遇到 datetime 报错

直接用 json.dumps() 处理含 datetime 对象的字典会抛出 TypeError: Object of type datetime is not JSON serializable。Python 标准库不支持原生序列化日期时间类型。

解决方法是传入 default 参数,提供一个可调用对象来转换非标准类型:

import json
from datetime import datetime

data = {"name": "Alice", "created_at": datetime.now()}

json_str = json.dumps(data, default=lambda obj: obj.isoformat() if hasattr(obj, 'isoformat') else None)

输出类似:{"name": "Alice", "created_at": "2025-05-20T14:23:11.123456"}

  • 优先用 obj.isoformat(),它比 str(obj) 更规范、可逆性强
  • 避免在 default 中无条件返回 str(obj),否则可能把意外类型(如自定义类、bytes)也转成字符串,掩盖真正问题
  • 如果需要 UTC 时间,记得先调用 obj.astimezone(timezone.utc)isoformat()

用 json.loads 反序列化后还原 datetime 对象

json.loads() 默认只返回 dictliststr 等基础类型,不会自动把 ISO 格式字符串变回 datetime。得靠 object_hook 手动识别和转换。

常见做法是在加载时扫描 key 名或值格式:

import json
from datetime import datetime

def datetime_hook(d): for k, v in d.items(): if k == "created_at" and isinstance(v, str): try: d[k] = datetime.fromisoformat(v.replace("Z", "+00:00")) except ValueError: pass return d

data = json.loads('{"name": "Alice", "created_at": "2025-05-20T14:23:11.123456"}', object_hook=datetime_hook)

  • 不要全局匹配所有字符串字段——容易误转 ID、手机号等纯数字字符串
  • fromisoformat() 支持带 Z 的 UTC 表示,但需手动替换为 +00:00,否则报错
  • 若字段名不固定(比如日志中多个时间字段),可用正则匹配 r"^(at|time|date|ts)$" 这类后缀

序列化自定义类实例时绕过 __dict__ 陷阱

直接对类实例调用 json.dumps(obj) 会失败;有人习惯写 json.dumps(obj.__dict__),但这有隐患:丢失方法、忽略私有属性(_attr)、跳过 property 计算属性、无法处理循环引用。

更可控的方式是显式定义导出逻辑:

class User:
    def __init__(self, name, joined_at):
        self.name = name
        self.joined_at = joined_at
        self._internal_id = 123  # 不应被序列化
def to_dict(self):
    return {
        "name": self.name,
        "joined_at": self.joined_at.isoformat(),
        "is_active": True  # 可加入计算字段
    }

user = User("Bob", datetime.now()) json.dumps(user.to_dict())

  • 别依赖 __dict__,尤其当类用了 __slots__ 或 dataclass + __post_init__ 时,__dict__ 可能为空或不完整
  • 如果类结构复杂且多处复用,可封装一个通用 as_json() 方法,内部统一处理 datetime、枚举、嵌套对象
  • 想保持接口简洁,也可重载 __json__() 方法(非标准,但部分工具链识别),不过仍推荐显式 to_dict()

处理中文、特殊字符与缩进时的编码细节

默认情况下 json.dumps() 会将非 ASCII 字符(如中文)转义为 \uXXXX,且输出无空格。这不利于调试和人工阅读。

两个关键参数必须明确设置:

json.dumps(data, ensure_ascii=False, indent=2)
  • ensure_ascii=False 是硬性要求,否则中文变 \u4f60\u597d,后续系统若没正确 decode 就乱码
  • indent=2 仅用于开发或日志,线上 API 响应建议保持默认(无缩进),减少传输体积
  • 若要兼容旧版 Python(default 返回 date 对象——json 模块不认它,得先转成 datetime 或字符串

最易被忽略的是时区信息:没有显式标注时区的 datetime 对象,isof

ormat() 输出不带 offset,反序列化后仍是“本地时间”语义,跨系统传递时极易出错。宁可全链路强制用 UTC 并显式标注。


# python  # js  # json  # 编码  # 工具  # 解决方法  # 标准库  # Object  # 封装  # date  # 字符串  # 循环  # 接口  # Property  # 对象  # default  # ASCII  # 序列化  # 自定义  # 报错  # 转成  # 的是  # 非标准  # 是在  # 多个  # 也可  # 用了 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251811 】 【 AI营销90571


相关推荐: 如何自定义建站之星网站的导航菜单样式?  如何快速搭建虚拟主机网站?新手必看指南  EditPlus中的正则表达式实战(5)  网站制作企业,网站的banner和导航栏是指什么?  Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】  EditPlus中的正则表达式 实战(1)  清除minerd进程的简单方法  教学论文网站制作软件有哪些,写论文用什么软件 ?  Win11怎么开启自动HDR画质_Windows11显示设置HDR选项  html5的keygen标签为什么废弃_替代方案说明【解答】  Python文件异常处理策略_健壮性说明【指导】  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧  网站建设保证美观性,需要考虑的几点问题!  Python文件流缓冲机制_IO性能解析【教程】  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  Linux网络带宽限制_tc配置实践解析【教程】  java中使用zxing批量生成二维码立牌  如何用AWS免费套餐快速搭建高效网站?  HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】  长沙做网站要多少钱,长沙国安网络怎么样?  魔方云NAT建站如何实现端口转发?  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  如何彻底删除建站之星生成的Banner?  公司网站制作需要多少钱,找人做公司网站需要多少钱?  Python3.6正式版新特性预览  微信h5制作网站有哪些,免费微信H5页面制作工具?  大学网站设计制作软件有哪些,如何将网站制作成自己app?  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法  如何将凡科建站内容保存为本地文件?  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  千库网官网入口推荐 千库网设计创意平台入口  简单实现Android验证码  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率  在Oracle关闭情况下如何修改spfile的参数  Python企业级消息系统教程_KafkaRabbitMQ高并发应用  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  浏览器如何快速切换搜索引擎_在地址栏使用不同搜索引擎【搜索】  Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】  微信小程序 HTTPS报错整理常见问题及解决方案  打开php文件提示内存不足_怎么调整php内存限制【解决方案】  Laravel如何使用Eloquent进行子查询  Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程  Laravel安装步骤详细教程_Laravel环境搭建指南  常州企业网站制作公司,全国继续教育网怎么登录?  公司门户网站制作流程,华为官网怎么做?