如何在Pydantic v2中复刻Pydantic v1的json_encoders行为?
Pydantic v2 复刻v1 json_encoders处理容器内元素的方法
Pydantic v2 中json_encoders默认仅对显式声明类型的字段生效,因此列表这类容器内的bytes元素不会触发自定义编码逻辑。要复刻v1的行为,有两种实用方案:
方案1:给列表字段指定明确的元素类型
将列表字段的类型从list改为list[bytes],让Pydantic识别到列表元素的具体类型,自动应用自定义编码器:
from pydantic import BaseModel, Field, ConfigDict class Foo(BaseModel): foo_bytes: bytes foo_params: list[bytes] = Field(default_factory=list) model_config = ConfigDict(json_encoders={ bytes: lambda x: f"0x{x.hex()}" }) foo_data = bytes(b"hello_world") foo = Foo(foo_bytes=foo_data, foo_params=[foo_data]) print(foo.model_dump_json()) # 输出: '{"foo_bytes":"0x68656c6c6f5f776f726c64","foo_params":["0x68656c6c6f5f776f726c64"]}'
方案2:自定义全局JSON编码器
如果需要对所有场景下的bytes(包括任意容器内的)统一应用自定义编码,可以继承PydanticJsonEncoder重写default方法,再在模型配置中指定该编码器:
from pydantic import BaseModel, Field, ConfigDict from pydantic.json import PydanticJsonEncoder class CustomJsonEncoder(PydanticJsonEncoder): def default(self, obj): if isinstance(obj, bytes): return f"0x{obj.hex()}" return super().default(obj) class Foo(BaseModel): foo_bytes: bytes foo_params: list = Field(default_factory=list) model_config = ConfigDict(json_encoder=CustomJsonEncoder) foo_data = bytes(b"hello_world") foo = Foo(foo_bytes=foo_data, foo_params=[foo_data]) print(foo.model_dump_json()) # 输出: '{"foo_bytes":"0x68656c6c6f5f776f726c64","foo_params":["0x68656c6c6f5f776f726c64"]}'
两种方案区别:
- 方案1更精准,仅针对指定类型的列表元素生效
- 方案2是全局生效,所有未被Pydantic默认处理的bytes都会使用自定义逻辑编码
内容的提问来源于stack exchange,提问作者user2465039
相关产品推荐
相关产品推荐

