Pydantic系列之validator

Validators

四种validator

Pydantic提供了四种validator

  • BeforeValidator
    运行在Pydantic内部的校验转换之前,入参为输入值Any,返回值为Any。
  • AfterValidator
    运行在Pydantic内部的校验转换之后,入参和返回值为正确的字段类型。
  • PlainValidator
    运行时间和BeforeValidator相同,但执行完之后整个校验过程结束,不再执行其他validator和Pydantic内部的校验流程。
  • WrapValidator
    可以运行在pydantic和其他validator之前或者之后,或者返回值、抛出异常立即结束校验流程。

可以使用多个BeforeValidator、AfterValidator和WrapperValidator,但是只能有一个PlainValidator。

关于执行顺序,从右到左执行所有Before和Wrap校验器,再从左到右执行所有After校验器。

以下示例展示了validator的用法。

from typing import Any, List

from pydantic import BaseModel, ValidationError
from pydantic.functional_validators import AfterValidator, BeforeValidator, WrapValidator
from pydantic_core.core_schema import ValidatorFunctionWrapHandler, ValidationInfo
from typing_extensions import Annotated


def check_squares(v: int) -> int:
    print('square')
    assert v ** 0.5 % 1 == 0, f'{v} is not a square number'
    return v


def double(v: Any) -> Any:
    print('double')
    return v * 2


def maybe_strip_whitespace(
        v: Any, handler: ValidatorFunctionWrapHandler, info: ValidationInfo
) -> int:
    print('wrap')
    if not isinstance(v, int):
        v = int(v)
    if v >= 22:
        try:
            # 执行后续校验器链
            return handler(v)
        except ValidationError as e:
            print(e)
            return handler(v / 2)
    # 直接返回,结束校验
    return v


MyNumber = Annotated[int, AfterValidator(check_squares), WrapValidator(maybe_strip_whitespace), BeforeValidator(double)]


class DemoModel(BaseModel):
    number: List[MyNumber]

print(DemoModel(number=[8, '2']))
'''
double
wrap
double
wrap
square
1 validation error for ValidatorCallable
  Assertion failed, 22 is not a square number [type=assertion_error, input_value=22, input_type=int]
    For further information visit https://errors.pydantic.dev/2.1/v/assertion_error
square
1 validation error for DemoModel
number.1
  Assertion failed, 11 is not a square number [type=assertion_error, input_value=11.0, input_type=float]
    For further information visit https://errors.pydantic.dev/2.1/v/assertion_error
'''

@field_validator

  • field_validator可以是Before或者AfterValidator(默认)。
  • 被field_validator装饰的方法变成类方法(返回了classmethod),被装饰方法第一个参数是当前Model类,第二个参数为待校验的值,如果有第三个参数,则是pydantic.FieldValidationInfo,校验信息。
  • @field_validator可变参数是要校验的字段名,可以是多个,'*'表示所有字段。
  • check_fields关键字参数,检验字段是否存在在对象身上。
  • 要么抛出ValidationError和AssertionError,要么返回处理过的值。
import json
from typing import Type

from pydantic import BaseModel, field_serializer, field_validator, ValidationError
import builtins


class AppModel(BaseModel):
    tp: Type = float
	
	# 序列化float类为字符串'float'
    @field_serializer('tp')
    def ser_tp(self, value):
        return value.__name__
	
	# 反序列化'float'为 class float
    @field_validator('tp', mode='before')
    def validate_tp(cls, value):
        if isinstance(value, type):
            return value
        if isinstance(value, str):
            v = getattr(builtins, value, None)
            if v is not None:
                return v

        raise ValidationError('unknow type: ' + value)


js = AppModel(tp=float).model_dump_json()
print(js)
print(AppModel(**json.loads(js)))

字段校验按照定义的顺序进行,所以在使用ValidationInfo时需要注意访问的字段是否已经被校验处理过,如果要使用多个字段信息进行验证,可以使用@model_validator。

@model_validator

  • model_validator可以是mode=‘before’, mode=‘after’ or mode=‘wrap’。
  • mode=‘before’,装饰的方法是一个类方法,第一个参数是cls类,第二个参数是Dict[str, Any],即原始输入(如果没有被model='wrap’修改的话),第三个参数(如果有)是ValidationInfo,返回值是Dict[str, Any]。
  • mode=‘after’,在validator和pydantic校验完成之后调用,是实例方法,只有一个参数self,此时属性已在实例对象上。
  • mode=‘wrap’,类方法,在before之前被调用,第一个参数是cls,第二个参数是原始输入Dict[str, Any],第三个参数是ValidatorCallable校验器链,接受一个参数执行后续校验流程,第四个参数是ValidationInfo。

Special Types

  • SkipValidation,跳过验证
  • InstanceOf,相当于isincetance(obj, cls)
class Model(BaseModel):
    names: List[SkipValidation[str]]
    values: List[instanceOf[int]]

Validation Context

运行时动态修改校验行为,文档

### 关于 PyCharm 插件的信息 #### 创建 PyCharm 插件 创建 PyCharm 插件的过程基于 IntelliJ IDEA 平台,这是因为 PyCharm 的插件开发遵循与 Android Studio 类似的流程[^3]。开发者可以在 IntelliJ IDEA 上构建插件项目而不必额外添加 Python 依赖项。 对于特定应用领域如 Maya 软件的 PyCharm 插件开发环境搭建,则涉及到将 Maya 自带的 Pymel 库路径加入到 PyCharm 配置中作为第三方库的一部分[D:\Autodesk\Maya2019\Python\Lib\site-packages][^4]。这使得在为 Maya 编写脚本时能够更方便地调用相关模块和函数。 #### 使用 PyCharm 插件 以 Pydantic PyCharm 插件为例,此插件专为增强 Pydantic 数据验证库的功能而设计,适用于那些希望提高工作效率以及确保代码质量的开发者群体。安装完成后,它能提供诸如自动补全、错误检测等一系列辅助功能来简化工作流[^1]。 #### 推荐 PyCharm 插件 除了上述提到的 Pydantic 支持外,还有其他多种实用型插件可供选择。例如一些通用性的工具类插件可以帮助改善日常编程体验;而对于专注于 Web 或者机器学习项目的团队来说,则有专门定制化的解决方案等待探索[^2]。 ```python # 示例:展示如何简单配置PyCharm使用某个已知插件(假设是Pydantic) from pydantic import BaseModel, ValidationError, validator class User(BaseModel): name: str age: int @validator('age') def check_age(cls, v): if v < 0 or v > 120: raise ValueError('年龄应在合理范围内') return v try: user = User(name="张三", age=30) except ValidationError as e: print(e.json()) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值