annotated-types 完全指南:3步为 typing.Annotated 添加类型约束,告别无效数据
【免费下载链接】annotated-typesReusable constraint types to use with typing.Annotated项目地址: https://gitcode.com/gh_mirrors/an/annotated-types
Python 项目里age = -5这样的无效数据还能畅通无阻?annotated-types是一个专为typing.Annotated(PEP 593)声明类型约束的轻量 Python 库。3 步即可给数据加上清晰的"边界":年龄必须大于 18、列表长度不超过 10、字符串必须是纯数字。本篇完整指南从安装到全部常用约束类型一次讲清,新手也能快速上手。🎯
为什么需要类型约束?
普通的类型标注x: int只能告诉工具"这是个整数",却无法表达"是多大范围的整数"。想声明"年龄必须大于 18",以前要么自己手写运行时断言,要么依赖各验证框架的私有语法。
annotated-types提供的是一组现成的约束元数据类型(Gt、Ge、Lt、Le、Len、Predicate 等),与typing.Annotated搭配使用,可被 Pydantic 等下游库统一理解。两个值得先了解的设计点:
- 🪶极度轻量:库本身不做运行时校验,只负责"声明"约束,几乎没有性能开销
- 🤝生态标准:由 Pydantic 与 Hypothesis 维护者在 PyCon 2022 冲刺周共同设计,目标是成为整个 Python 生态的通用约束语言
3步快速上手
第1步:一键安装 annotated-types
要求 Python 3.10 及以上,直接用 pip 安装:
pip install annotated-types如果想阅读源码,可以克隆仓库:
git clone https://gitcode.com/gh_mirrors/an/annotated-types所有核心约束类型都实现在annotated_types/__init__.py这一个文件里,打开扫一遍就能对整体有个印象。
第2步:添加数值与长度约束
导入需要的约束类,写在Annotated的类型之后即可:
from typing import Annotated from annotated_types import Gt, Len class User: age: Annotated[int, Gt(18)] # 必须大于 18 scores: Annotated[list[int], Len(0, 10)] # 列表长度为 0~10Gt(18)表示"大于 18",Len(0, 10)表示"长度介于 0 到 10(含两端)"。同类的还有Ge(≥)、Lt(<)、Le(≤),也可以用Interval一次性给出上下界。
第3步:用 Predicate 写自定义校验
对于上下界表达不了的约束,比如"质数"或"纯数字字符串",Predicate可以把任意函数包装成约束——函数返回值真值时数据才合法:
from annotated_types import Predicate factors: list[Annotated[int, Predicate(is_prime)]] # 每个元素都必须是质数库内还内置了IsDigit(纯数字)、IsFinite(有限浮点数)等现成的泛型别名,可以直接写x: IsFinite[float],无需自己再包一层Predicate。
常用约束类型速查表
| 约束类型 | 含义 | 典型用法 |
|---|---|---|
Gt(x)/Ge(x) | 大于 / 大于等于 x | Annotated[int, Gt(18)] |
Lt(x)/Le(x) | 小于 / 小于等于 x | Annotated[int, Le(100)] |
Interval | 一次性指定上下界(可组合上面四种) | Interval(ge=1, le=10) |
MultipleOf(x) | 必须是 x 的倍数 | Annotated[int, MultipleOf(4)] |
MinLen/MaxLen/Len | 最小/最大长度(均含端点) | Annotated[str, Len(2, 8)] |
Timezone | 限定允许的时区 | Annotated[datetime, Timezone(None)] |
Unit | 声明数值的物理单位 | Annotated[float, Unit("m/s")] |
Predicate(func) | func(value) 为真即通过 | Predicate(is_prime) |
Not | 谓词的取反,仍可被内省识别 | Not(math.isfinite) |
doc("...") | 为参数附加文档说明 | Annotated[int, doc("用户ID")] |
💡 小细节:约束可以和可比类型自由搭配,例如
Annotated[int, Gt(1.5)]表示"大于 1.5 的整数",边界值不要求和被标注类型同类型。
常见问题 FAQ
Q1:annotated-types 会自动校验数据吗?
不会。它只携带约束描述,真正的校验由 Pydantic 等下游库读取元数据后执行——这正是它几乎零性能开销的原因。如何解析约束元数据,可以参考tests/test_main.py中的官方示例。
Q2:同一个字段能叠加多个约束吗?
可以。在Annotated中依次列出即可,例如Annotated[int, Ge(0), Le(100)]。对库作者而言,GroupedMetadata提供了把多条约束打包成一个对象的机制,Interval和Len本身就是分组元数据,相关测试见tests/test_grouped_metadata.py。
Q3:想要更多约束怎么办?
项目刻意保持最小化,只覆盖最常见的场景。官方建议:如果你有额外需求,在下游库中自定义并文档化自己的约束类型即可。设计思路详见README.md,项目构建配置见pyproject.toml。
写在最后
annotated-types把"数据边界"从口头约定变成了声明式标注,三步走完全程:
- ✅
pip install annotated-types一键安装 - ✅ 用
Gt/Ge/Lt/Le/Len添加常用数值与长度约束 - ✅ 用
Predicate表达任意自定义校验
掌握这个轻量库后,你的类型标注就不再是"标签",而会成为真正的数据契约。搭配 Pydantic 等验证框架,从此对无效数据说再见!🚀
【免费下载链接】annotated-typesReusable constraint types to use with typing.Annotated项目地址: https://gitcode.com/gh_mirrors/an/annotated-types
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考