orjson 不支持 dataclass 默认序列化,需先用 dataclasses.asdict() 转为字典再序列化;避免依赖默认行为,显式指定 dict_factory=dict;含 datetime、enum 等类型需提前转换;慎用 default 参数,优先走纯 c 路径以保性能与安全。

orjson 不支持 dataclass 默认序列化
直接用 orjson.dumps() 序列化一个 dataclass 实例会报错:TypeError: Type is not JSON serializable: MyDataClass。这不是 bug,是 orjson 的明确设计——它只支持内置类型(dict、list、str、int、float、bool、None)和少量扩展类型(如 datetime、bytes),不递归解析自定义类。
必须手动转成 dict 才能用 orjson
最稳妥的做法是先将 dataclass 转为字典,再交给 orjson.dumps()。别依赖 asdict() 的默认行为,它在嵌套或含不可序列化字段时容易静默失败。
- 用
dataclasses.asdict(obj, dict_factory=dict)显式指定dict_factory,避免意外返回OrderedDict等非原生类型 - 如果
dataclass含datetime字段,asdict()会保留datetime对象,而 orjson 默认支持它——但得确认你没禁用orjson.OPT_PASSTHROUGH_DATETIME - 含
Enum或自定义类型的字段,必须提前转换(例如重写__post_init__或用field(default_factory=...)配合预处理)
示例:
import dataclasses
import orjson
<p>@dataclasses.dataclass
class User:
name: str
created_at: datetime.datetime</p><p>user = User("alice", datetime.datetime.now())</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/shouce/1725" title="doxygen 官方手册"><img
src="https://img.php.cn/upload/manual/000/000/013/170658211183824.png" alt="doxygen 官方手册" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/shouce/1725" title="doxygen 官方手册">doxygen 官方手册</a>
<p>doxygen是一款好用的程序员辅助工具,它可以让程序添加批添代码更加简单轻松,兼容C++、 C、Java、 Objective-C、Python等主流编程语言,小编提供的doxygen中文手册包含了基本介绍、语法技巧以及进阶技巧等内容,可以让你快速上手操作,有需要的欢迎下载。 基本介绍 Doxygen已经支持生成ANSI编码的chm目录文件(index.hhc)!Doxygen通常是用作生成英文文档的,生成中文文档需要修改输入和输出的码制,这样可以改变解析方式,生成中文文档。但是,你必须意识 到,Dox</p>
</div>
<a href="/xiazai/shouce/1725" title="doxygen 官方手册" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/00968c3c2c15" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">Python免费学习笔记(深入)</a>”;</p><h1>✅ 正确:转 dict 后序列化</h1><p>payload = orjson.dumps(dataclasses.asdict(user))别碰 orjson 自定义 hook(除非你真需要)
orjson.dumps() 支持 default 参数,但它的调用时机和限制比 json.dumps() 更苛刻:只对“完全无法识别的类型”触发,且不能返回任意对象(比如返回 dict 后,里面若还有不支持的类型,不会递归调用)。
- 想靠
default=lambda x: x.__dict__暴力兜底?大概率失败——__dict__可能含方法、闭包、循环引用 - 如果真要用
default,只建议用于单一层级的简单包装类(如Id(int)),并确保返回值全是 orjson 原生支持类型 - 性能上,
default是纯 Python 回调,每次调用都有开销;而先asdict()再dumps()是纯 C 路径,更快也更可控
dataclass + orjson 的真实瓶颈不在序列化本身
很多人卡在“为什么加了 @dataclass 就变慢”,其实问题常出在构造阶段:比如用 field(default_factory=list) 却忘了加 default_factory,导致所有实例共享同一个 list;或者 __post_init__ 里做了 IO 或复杂计算。
- 检查是否误用了可变默认参数(
def __init__(self, tags=[]):)——这是 dataclass 陷阱,和 orjson 无关,但会污染数据 - 如果要高频序列化,考虑把
asdict()结果缓存为属性(用@property或__slots__配合__dict__预填充),避免重复构造字典 - orjson 的优势在于快和小,但如果 dataclass 本身结构混乱(比如混用
dict、list、NamedTuple),序列化前的规整成本可能盖过 orjson 的收益
真正要注意的,是 dataclass 定义是否干净、字段是否都可预测地映射到 JSON 基元——这比选哪个序列化库影响更大。









