You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在Pydantic v2中如何定义可复用的带约束Annotated[str]类型(以校验和验证器为例)

在Pydantic v2中如何定义可复用的带约束Annotated[str]类型(以校验和验证器为例)

我完全理解你的困惑——从Pydantic v1转到v2时,类型注解的用法确实有不少变化,尤其是复用自定义约束类型这块。咱们一步步来解决你的问题:

先解决你遇到的直接报错

你写的代码里special_string = Annotated[...]是错误的,Pydantic v2要求模型字段必须用类型注解的方式(也就是字段名: 类型),而不是直接赋值。正确的基础写法应该是:

from typing import Annotated
from pydantic import BaseModel, StringConstraints

class GeneralThing(BaseModel):
    special_string: Annotated[str, StringConstraints(pattern="^[a-fA-F0-9]{64}$")]

核心需求:定义可复用的约束类型

你不想每次都重复写长长的Annotated[str, StringConstraints(...)],而是想像v1那样用一个简洁的类型名(比如ChecksumStr)来复用,这在v2里完全可以实现——只要把这个Annotated组合定义成一个类型别名就行:

步骤1:定义可复用的校验和类型

from typing import Annotated
from pydantic import StringConstraints

# 把带约束的Annotated类型封装成别名,方便复用
ChecksumStr = Annotated[str, StringConstraints(pattern="^[a-fA-F0-9]{64}$")]

步骤2:在模型中复用这个类型

现在你可以在任何模型里直接引用ChecksumStr,和你之前v1的写法一样简洁:

from pydantic import BaseModel

class GeneralThing(BaseModel):
    special_string: ChecksumStr

class AnotherThing(BaseModel):
    file_checksum: ChecksumStr
    transaction_checksum: ChecksumStr

扩展:添加自定义验证逻辑

如果你的校验需求不止正则(比如要验证是有效的SHA-256),可以结合BeforeValidatorAfterValidator来扩展这个复用类型:

from typing import Annotated
from pydantic import StringConstraints, BeforeValidator

def validate_sha256_validity(value: str) -> str:
    # 额外验证:确保是有效的十六进制字符串
    try:
        int(value, 16)
    except ValueError:
        raise ValueError("无效的十六进制校验和")
    # 验证长度(其实正则已经包含,但这里作为示例)
    if len(value) != 64:
        raise ValueError("SHA-256校验和必须是64个字符")
    return value

# 组合正则约束和自定义验证器
ChecksumStr = Annotated[
    str,
    StringConstraints(pattern="^[a-fA-F0-9]{64}$"),
    BeforeValidator(validate_sha256_validity)
]

这样定义的ChecksumStr不仅可以在Pydantic模型里用,还能用于函数参数的类型注解,完全贴合Python 3.9+的类型提示系统。

备注:内容来源于stack exchange,提问作者nerdstrike

火山引擎 最新活动