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
相关产品推荐
相关产品推荐

