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

Pydantic能否实现基于指定字段(如_operation)的多态JSON序列化与反序列化?

Pydantic实现自定义鉴别器字段的多态处理

Pydantic完全支持类似Jackson的多态序列化/反序列化,且能实现自定义鉴别器字段(比如你提到的_operation)不保留在反序列化后的对象中,下面是具体实现方案(基于Pydantic v2):

1. 定义基类与子类

通过Annotated结合Discriminator指定鉴别器字段,同时在基类中将该字段设置为exclude=True,确保它不会出现在最终的对象实例中:

from pydantic import BaseModel, Field, Discriminator
from typing import Annotated, Union

# 基类
class Operation(BaseModel):
    _operation: str = Field(exclude=True)  # exclude=True 确保该字段不保留在对象中

# 子类:创建操作
class CreateOperation(Operation):
    _operation: str = "create"
    resource_id: str
    payload: dict

# 子类:更新操作
class UpdateOperation(Operation):
    _operation: str = "update"
    resource_id: str
    delta: dict

# 用Annotated+Discriminator指定多态类型的鉴别规则
OperationType = Annotated[
    Union[CreateOperation, UpdateOperation],
    Discriminator("_operation")
]

2. 序列化(对象转JSON)

序列化时,鉴别器字段_operation会被自动包含在JSON输出中:

create_op = CreateOperation(resource_id="res123", payload={"name": "test"})
print(create_op.model_dump_json(indent=2))
# 输出:
# {
#   "_operation": "create",
#   "resource_id": "res123",
#   "payload": {"name": "test"}
# }

3. 反序列化(JSON转对象)

反序列化时,Pydantic会根据_operation字段的值自动匹配对应的子类,且最终的对象实例中不会包含_operation字段:

update_json = '''
{
  "_operation": "update",
  "resource_id": "res123",
  "delta": {"name": "new_test"}
}
'''

update_op = OperationType.model_validate_json(update_json)
print(type(update_op))  # <class '__main__.UpdateOperation'>
print(update_op.model_dump())
# 输出:{'resource_id': 'res123', 'delta': {'name': 'new_test'}}
# 可以看到_operation字段不在最终对象中

关键说明

  • Discriminator("_operation"):告诉Pydantic用_operation字段的值来区分不同的子类
  • Field(exclude=True):标记该字段在序列化/反序列化后不保留在对象实例中,仅作为类型鉴别用
  • 若使用Pydantic v1,语法略有不同,需用Union结合Config和discriminator参数,但v2的方案更简洁,推荐使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 01:50:20