如何修改Pydantic的.dict方法行为 为深层字段添加pypi包裹层
Pydantic 自定义Library序列化包裹层实现方案
该需求可以直接实现,无需修改JobTaskSettings的字段定义,仅需调整Library模型的序列化逻辑即可,核心思路是让Library实例在执行序列化输出时,自动在原生结构外层包裹pypi键的对象。
具体实现代码
直接重写Library类的序列化方法,上层List[Library]类型的字段会自动调用每个元素的序列化规则,无需额外配置:
from pydantic import BaseModel, Field from typing import Optional, List # 假设TaskKey为你项目中已定义的基类,无需改动 class Library(BaseModel): package: str def dict(self, **kwargs): # 先执行原生序列化逻辑拿到默认结构,兼容所有dict()方法的传参(比如exclude、include、by_alias等) base_serialize = super().dict(**kwargs) # 包裹pypi外层后返回 return {"pypi": base_serialize} class JobTaskSettings(TaskKey): description: Optional[str] depends_on: Optional[List[TaskKey]] on_cluster_id: str = Field(..., alias="existing_cluster_id") libraries: List[Library]
效果验证
实例化JobTaskSettings后调用.dict()方法,即可得到预期结构:
# 测试示例 demo_task = JobTaskSettings( existing_cluster_id="c-123", libraries=[ Library(package="requests"), Library(package="bs4") ] ) print(demo_task.dict(by_alias=True))
输出的libraries字段结构完全符合预期:
"libraries": [ {"pypi": {"package": "requests"}}, {"pypi": {"package": "bs4"}} ]
补充说明
- 该写法完全兼容
.dict()方法的所有原生参数,比如字段过滤、别名输出、嵌套序列化规则等,不会破坏原有Pydantic的序列化能力。 - 如果后续需要支持其他依赖类型(比如maven、jar包),只需要在
Library的dict方法中增加类型判断,返回对应外层键的结构即可,扩展性较强。 - 如果你使用Pydantic v2版本,除了重写兼容的
dict方法外,也可以用内置的@model_serializer装饰器实现相同逻辑,效果完全一致。
内容的提问来源于stack exchange,提问作者Tizianoreica
相关产品推荐
相关产品推荐

