Pydantic BaseModel类如何在实例创建时自动转换指定字段值
实现方法
Pydantic 在类定义阶段就通过元类内置了初始化流程,自动完成类型校验和值解析,不需要手动重写__init__方法。直接使用框架提供的字段校验装饰器,即可在初始化流程中嵌入自定义值转换逻辑,既保留Pydantic全部的内置校验能力,也能实现“实例创建时自动完成字段值转换”的需求。
Pydantic V2(官方当前主流版本)实现
完整可运行代码如下:
from typing import Any, List from pydantic import BaseModel, field_validator class MyModel(BaseModel): foo: List[str] @field_validator("foo", mode="before") @classmethod def convert_foo_value(cls, value: Any) -> List[str]: # 兼容单字符串入参,自动包装为单元素列表 if isinstance(value, str): value = [value] # 对列表内所有元素完成短横转下划线的替换 return [s.replace("-", "_") for s in value]
运行效果
- 传入单字符串
MyModel(foo="hello-there")时,无需额外操作,实例的foo字段会自动变为["hello_there"] - 传入多元素列表
MyModel(foo=["a-b", "c-d"])时,会逐元素完成替换,最终结果为["a_b", "c_d"] - 校验器设置
mode="before"意味着自定义转换逻辑会在Pydantic默认的List[str]类型校验之前执行,既兼容了单字符串入参的特殊场景,也不会破坏原有类型校验的有效性。 - 如果不需要兼容单字符串入参,仅需对标准列表入参做元素替换,可以去掉
mode="before"设置,此时校验器会在Pydantic完成类型校验后直接对合法的List[str]值做转换,逻辑更简洁。
Pydantic V1(旧版本)实现
如果项目使用的是Pydantic V1,语法略有调整,通过内置validator装饰器实现相同逻辑:
from typing import Any, List from pydantic import BaseModel, validator class MyModel(BaseModel): foo: List[str] @validator("foo", pre=True) @classmethod def convert_foo_value(cls, value: Any) -> List[str]: if isinstance(value, str): value = [value] return [s.replace("-", "_") for s in value]
关于重写
__init__的说明:如果手动给Pydantic模型重写__init__方法,会覆盖框架内置的校验挂载逻辑,要么丢失类型校验能力,要么需要手动处理父类初始化调用,复杂度更高,也容易出现跨版本兼容问题,因此官方更推荐通过校验器实现自定义值转换。
内容的提问来源于stack exchange,提问作者Jivan
相关产品推荐
相关产品推荐

