You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.10与3.11中Enum成员YAML序列化差异原因探究

Python 3.10与3.11中Enum序列化YAML的输出差异原因

测试代码

import sys
import yaml
try:
    from enum import ReprEnum
except ImportError:
    from enum import Enum as ReprEnum


class MyEnum(int, ReprEnum):
    foo = 123


print('Python version:', ''.join(map(str, sys.version_info[:3])))
print(yaml.dump({'test': MyEnum.foo}))

Python 3.10输出

Python version: 3.10.12
test: !!python/object/apply:__main__.MyEnum
- 123

Python 3.11输出

Python version: 3.11.4
test: !!python/object/apply:builtins.getattr
- !!python/name:__main__.MyEnum ''
- foo

差异原因

这个差异完全源于Python 3.11对Enum模块序列化逻辑的改动,具体细节如下:

  1. 序列化核心逻辑变更
    Python 3.10及更早版本中,Enum实例的序列化依赖「通过枚举值重建实例」的逻辑,对应实例的__reduce__方法会返回(枚举类, (成员值,)),PyYAML据此生成直接调用枚举类并传入值的YAML结构。

而Python 3.11开始,Enum改用「基于成员名称引用」的序列化方式,__reduce__方法返回(getattr, (枚举类, 成员名称))。这种改动是为了解决枚举类中可能存在的「值重复但成员名称不同」的场景,确保反序列化时能精准还原到对应的枚举成员,避免歧义。

  1. PyYAML的适配逻辑
    PyYAML序列化Python对象时,会严格遵循对象__reduce__方法返回的信息生成对应YAML标签。因此当Enum的__reduce__返回值改变后,PyYAML输出的结构自然随之变化:
  • 3.10版本直接调用枚举类构造实例
  • 3.11版本通过getattr从枚举类中获取指定名称的成员

内容的提问来源于stack exchange,提问作者ThiefMaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 11:37:14