装饰器机制与自定义示例见 00.概念-装饰器机制。
选型指引(我想… → 用哪个)
| 你想做的事 | 优先选 | 别误选 |
|---|---|---|
方法当属性读(obj.x 不要括号) |
@property |
每次都要最新值且昂贵 → 见下行 |
| 属性首次算完就缓存 | @cached_property |
跨实例共享、无 self → @lru_cache |
| 纯函数相同参数不想重复算 | @lru_cache / @cache |
依赖 self 的实例属性 → @cached_property |
| 写命令行工具(子命令、–help) | @click.* |
只有 2 个参数 → argparse 也够 |
| 写 HTTP API、要 OpenAPI 文档 | @app.get/post |
全请求日志/CORS → 中间件 |
| 端点里注入 DB、当前用户 | Depends(...) |
每个路由都要、与参数无关 → 中间件 |
| 每个请求统一加头、计时、鉴权短路 | @app.middleware |
只个别路由要 → 路由级 Depends |
| JSON/配置模型字段校验 | @field_validator + BaseModel |
单个工具函数 → @validate_call |
| 普通函数按类型注解校验入参 | @validate_call |
复杂嵌套 JSON → BaseModel |
| 记录函数调用/异常(自定义) | @log_call 模式 |
HTTP 访问日志 → FastAPI 中间件 |
| 自己写装饰器别丢函数名 | @wraps |
— |
| 测试共享 setup/teardown | @pytest.fixture |
只测一组参数 → @parametrize |
| 函数暴露给 LLM 客户端调用 | @mcp.tool() |
— |
| 程序退出前清理资源 | @atexit.register |
必须保证的清理 → try/finally |
| 同函数名按参数类型分派 | @singledispatch |
多个参数类型组合 → multipledispatch |
| 枚举成员 value 不能重复 | @enum.unique |
故意 alias 同值 → 不要加 |
少写 __init__/repr 的数据类 |
@dataclass |
要严格运行时校验 → Pydantic |
| 子类必须实现某方法 | @abstractmethod |
不强制继承 → Protocol |
| 工厂方法、访问类状态 | @classmethod |
完全不需要 cls → @staticmethod |
| 工具函数挂在类命名空间里 | @staticmethod |
要访问实例 → 实例方法 |
总表
| 作用对象 | 使用场景 | 名称 | 一句话简介 | 来源 | 专篇 |
|---|---|---|---|---|---|
| 类 | 属性访问 | @property |
把方法变成属性访问,可加 setter 做校验 | 标准库 | 类-属性访问-property |
| 类 | 属性访问 | @cached_property |
实例属性首次访问后缓存,适合昂贵计算 | 标准库 functools | 类-属性访问-cached_property |
| 类 | 方法绑定 | @classmethod |
绑定到类,首参 cls,可工厂构造 |
标准库 | 类-方法绑定-classmethod |
| 类 | 方法绑定 | @staticmethod |
不注入 self/cls,类命名空间下的工具函数 | 标准库 | 类-方法绑定-staticmethod |
| 类 | 抽象 | @abstractmethod |
抽象基类强制子类实现,否则不能实例化 | 标准库 abc | 类-抽象-abstractmethod |
| 类 | 元编程 | @dataclass |
按字段注解自动生成 init/repr/eq 等 | 标准库 dataclasses | 类-元编程-dataclass |
| 函数 | CLI | @click.* |
构建带子命令、选项、帮助的 CLI | click | 函数-cli参数-click |
| 函数 | 路由 | @app.get/post |
把函数注册为 HTTP 端点并生成 OpenAPI | FastAPI | 函数-路由-FastAPI |
| 函数 | 依赖 | Depends(...) |
端点参数声明式注入 DB/用户等可复用依赖 | FastAPI | 函数-依赖-Depends |
| 函数 | 中间件 | @app.middleware |
包裹每个请求,在进路由前后统一处理 | FastAPI/Starlette | 函数-中间件-middleware |
| 函数 | 校验 | @field_validator 等 |
模型字段/整体验证、序列化定制 | Pydantic v2 | 函数-校验-pydantic |
| 函数 | 校验 | @validate_call |
不建模型,按函数注解校验每次调用 | Pydantic v2 | 函数-校验-validate_call |
| 函数 | 日志 | @log_call |
自定义:记录调用、耗时、异常 | logging 模式 | 函数-日志-logging |
| 函数 | 元编程 | @wraps |
自定义装饰器时保留原函数名与 docstring | 标准库 functools | 函数-元编程-wraps |
| 函数 | 测试 | @pytest.fixture |
测试依赖注入,支持 scope 与 teardown | pytest | 函数-测试-pytest.fixture |
| 函数 | 服务注册 | @mcp.tool() |
把 Python 函数注册为 MCP 工具供 LLM 调用 | mcp | 函数-服务注册-mcp.tool |
| 函数 | 生命周期 | @atexit.register |
进程正常退出时执行清理函数 | 标准库 | 函数-生命周期-atexit.register |
| 函数 | 多态分发 | @singledispatch |
同一函数名按第一个参数类型选实现 | 标准库 | 函数-多态分发-singledispatch |
| 函数 | 缓存 | @lru_cache / @cache |
纯函数结果缓存,相同参数直接返回 | 标准库 functools | 函数-缓存-lru_cache |
| 枚举 | 唯一约束 | @unique |
枚举类成员 value 重复则在定义时报错 | 标准库 enum | 枚举-唯一约束-enum.unique |
按使用场景浏览
CLI
| 名称 | 简介 | 专篇 |
|---|---|---|
@click.* |
命令/子命令/选项/参数一体化,自动生成 --help |
函数-cli参数-click |
路由 / Web(FastAPI)
| 名称 | 简介 | 专篇 |
|---|---|---|
@app.get/post、@router.* |
绑定 URL 与 HTTP 方法,解析请求、约束响应 | 函数-路由-FastAPI |
Depends(...) |
把「拿 DB/验 token」从业务函数里拆出来复用 | 函数-依赖-Depends |
@app.middleware("http") |
全站请求洋葱包装:计时、CORS、请求 ID 等 | 函数-中间件-middleware |
属性访问
| 名称 | 简介 | 专篇 |
|---|---|---|
@property |
对外像字段,对内可以是方法 + 校验 | 类-属性访问-property |
@cached_property |
像 property,但只算一次后写入实例 | 类-属性访问-cached_property |
方法绑定
| 名称 | 简介 | 专篇 |
|---|---|---|
@classmethod |
不实例化也能调,需要知道「哪个类」 | 类-方法绑定-classmethod |
@staticmethod |
逻辑上属于类,但既不碰实例也不碰类状态 | 类-方法绑定-staticmethod |
抽象
| 名称 | 简介 | 专篇 |
|---|---|---|
@abstractmethod |
接口契约:子类不实现就实例化不了 | 类-抽象-abstractmethod |
校验
| 名称 | 简介 | 专篇 |
|---|---|---|
@field_validator / @model_validator |
结构化数据(API Body、配置类)的规则集中写 | 函数-校验-pydantic |
@validate_call |
给已有函数加一层「按注解检查入参」 | 函数-校验-validate_call |
日志
| 名称 | 简介 | 专篇 |
|---|---|---|
@log_call(自定义) |
函数级 enter/exit/exception 日志,非 HTTP 专用 | 函数-日志-logging |
元编程
| 名称 | 简介 | 专篇 |
|---|---|---|
@dataclass |
声明字段即可,少写样板构造与 repr | 类-元编程-dataclass |
@wraps |
写装饰器时的标配,避免 wrapper 吞元数据 | 函数-元编程-wraps |
测试
| 名称 | 简介 | 专篇 |
|---|---|---|
@pytest.fixture |
测试函数通过参数名声明「我需要这个准备环境」 | 函数-测试-pytest.fixture |
服务注册
| 名称 | 简介 | 专篇 |
|---|---|---|
@mcp.tool() |
FastMCP 把函数变成 LLM 可调用的工具 schema | 函数-服务注册-mcp.tool |
生命周期
| 名称 | 简介 | 专篇 |
|---|---|---|
@atexit.register |
解释器正常退出前的最后一道清理钩子 | 函数-生命周期-atexit.register |
多态分发
| 名称 | 简介 | 专篇 |
|---|---|---|
@singledispatch |
代替一长串 isinstance,按类型扩展行为 |
函数-多态分发-singledispatch |
缓存
| 名称 | 简介 | 专篇 |
|---|---|---|
@lru_cache / @cache |
函数级 memoization,参数作缓存键 | 函数-缓存-lru_cache |
唯一约束
| 名称 | 简介 | 专篇 |
|---|---|---|
@enum.unique |
防止两个枚举成员不小心用了相同 value | 枚举-唯一约束-enum.unique |
Click 子装饰器速查
| 子装饰器 | 简介 | 何时用 |
|---|---|---|
@click.group() |
命令容器,下面挂多条子命令 | git 式 app cmd subcmd |
@click.command() |
单条可执行命令 | 叶子命令 |
@click.option() |
--flag / -f 可选参数 |
开关、默认值、类型转换 |
@click.argument() |
位置参数 | cli.py input.txt 这种 |
@click.pass_context |
注入 ctx,组间共享状态 |
子命令读父级配置 |
@click.pass_obj |
注入 ctx.obj 简写 |
同上,少写一层 |
@click.version_option() |
自动 --version |
发布 CLI 时 |
@click.confirmation_option() |
执行前 y/n 确认 | 删除、覆盖等危险操作 |
@click.password_option() |
不回显输入 | 密码、token |
详细参数与示例见 函数-cli参数-click。
Pydantic 校验装饰器速查
| 装饰器 | 简介 | 何时用 |
|---|---|---|
@field_validator |
单个字段清洗/校验 | 非空、范围、格式 |
@model_validator |
整模型或跨字段规则 | end >= start 类约束 |
@field_serializer |
控制导出 JSON 时长什么样 | 脱敏、格式化 |
@validate_call |
装饰普通函数而非 BaseModel | 内部工具函数轻量 guard |