装饰器 · validate_call

0. 一句话定位

维度 内容
作用对象 函数
使用场景 校验
来源 第三方 pydantic v2(pydantic.validate_call
语法形式 @validate_call / @validate_call(config=...)

1. 做什么

包装普通函数:调用时根据类型注解校验并 coercion 参数;若声明了返回值注解也会校验返回值;失败抛 ValidationError。适合不想建 BaseModel 的轻量边界。

2. 重点参数

参数 类型 默认值 作用 配置建议
config ConfigDict 默认 校验行为配置 arbitrary_types_allowed=True
validate_return bool True 是否校验返回值 调试时可关

装饰器也可 @validate_call(validate_return=False) 等形式,以版本文档为准。

3. 最小可运行示例

1
2
3
4
5
6
7
8
9
10
11
12
13
from pydantic import validate_call, ValidationError

@validate_call
def add(a: int, b: int) -> int:
return a + b

print(add(1, 2)) # 3
print(add("3", 4)) # 7,coerce "3" -> 3

try:
add(1, "x")
except ValidationError as e:
print(e.error_count()) # 校验失败

约束与默认值

1
2
3
4
5
6
7
8
9
from typing import Annotated
from pydantic import Field

@validate_call
def create_user(name: Annotated[str, Field(min_length=1)], age: int = 18):
return {"name": name, "age": age}

print(create_user("bob"))
print(create_user(name="a", age=25))

4. 常见变体

校验返回值

1
2
3
@validate_call
def broken() -> int:
return "not int" # ValidationError on return

配合 Field / AfterValidator

1
2
3
4
5
6
7
8
9
10
from pydantic import AfterValidator

def strip_lower(v: str) -> str:
return v.strip().lower()

@validate_call
def tag(name: Annotated[str, AfterValidator(strip_lower)]) -> str:
return name

print(tag(" Hello ")) # hello

5. 适用 / 不适用

适用

  • 内部工具函数、脚本入口、MCP tool 前的轻量 guard
  • 已有类型注解,希望运行时 enforcement

不适用

  • 复杂嵌套 JSON / OpenAPI schema → BaseModel
  • 性能极敏感热路径(每次调用有校验开销)
  • 需要详细 JSON Schema 文档 → 模型类更合适

6. 易踩坑

  • 无类型注解的参数不会被校验
  • 与标准库 @dataclass 无直接关系;校验的是函数调用边界
  • 异步函数:@validate_call 支持 async(pydantic 2.x),wrapper 须 await
  • 错误信息是 ValidationError,与 FastAPI 422 格式不同,HTTP 层需自行转换

7. 近邻替代

替代 何时用
BaseModel + @field_validator 结构化数据、FastAPI Body
typeguard 仅检查类型、弱 coercion
手动 if 校验 极简脚本

8. 参考

-------------本文结束感谢您的阅读-------------