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

如何使用Pydantic validator校验数据?附自定义校验代码错误排查

Pydantic常用数据校验与清洗技术 + 代码问题排查

一、Pydantic常用数据校验清洗技术

  • 基础类型校验:直接在字段上声明类型(如str/int/datetime等),Pydantic会自动完成类型转换和合法性校验,无需手动写基础判断逻辑
  • 自定义校验器:通过@validator装饰器实现单字段/多字段的自定义规则校验、值标准化清洗,支持配置校验执行顺序、跨字段关联校验等
  • 可选字段与默认值:配合Optional类型、default参数实现非必填字段的兼容处理
  • 复杂结构校验:原生支持嵌套模型、列表、字典等复杂数据结构的递归校验
  • 内置字段约束:可通过Field参数快速配置数字范围(gt/lt)、字符串长度(min_length/max_length)、正则匹配(regex)等规则,无需手写校验逻辑
  • 自动序列化:校验通过后可直接输出标准化的字典、JSON格式数据,完成数据清洗落地

二、提交代码的错误点排查

  1. name字段校验逻辑与命名不符:函数名name_must_contain_space语义是要求姓名必须包含空格,但实际逻辑仅校验字符范围,没有判断是否存在空格的逻辑,命名语义不匹配
  2. age字段校验逻辑完全冗余且有bug:你已经将age声明为int类型,Pydantic会自动完成类型转换和校验,不需要手动判断;且if not (int(v))逻辑会误判合法值0为不合法,同时抛出的AttributeError不是Pydantic可识别的校验异常类型,校验失败时无法被正常捕获
  3. streetadr字段校验逻辑失效:if '' not in v的判断永远为假(空字符串属于任何字符串的子串),整个校验条件永远不会触发,等于未做校验;且v.isalnum()的判断逻辑有误,合法地址中包含空格时会被误判为不合法
  4. 缺少校验异常捕获逻辑:代码未捕获ValidationError,一旦传入非法数据会直接崩溃退出,生产环境无法正常处理异常场景

三、修正后的参考代码

from pydantic import BaseModel, ValidationError, validator

class UserModel(BaseModel):
    name: str
    age: int
    streetadr: str

    @validator('name')
    def name_only_letters_and_space(cls, v):
        # 优化校验逻辑,用集合判断替代遍历,性能更高
        allowed_chars = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ')
        if not set(v).issubset(allowed_chars):
            raise ValueError('名称只能包含英文字母和空格')
        # 若需要强制要求姓名包含空格可补充以下逻辑
        # if ' ' not in v:
        #     raise ValueError('名称必须包含空格')
        return v.title()

    @validator('streetadr')
    def street_address_valid(cls, v):
        # 明确允许地址包含的字符:字母、数字、空格
        allowed_chars = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ')
        if not set(v).issubset(allowed_chars):
            raise ValueError('地址只能包含英文字母、数字和空格')
        return v 

class GroupModel(BaseModel):
    users: UserModel

if __name__ == '__main__':
    try:
        u = GroupModel(users={'name':"james Wash", 'age':"23", 'streetadr':'2333 Sabrina Dr'})
        print(u.json(indent=2, ensure_ascii=False))
    except ValidationError as e:
        print(f"校验失败:{e.errors()}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 06:27:03