装饰器链本质是高阶函数的连续应用,每个装饰器接收函数并返回新函数,执行顺序从内到外;手动链式调用如log_calls(measure_time(f)),@语法按从下到上书写;需用args/*kwargs和@functools.wraps保持元信息与参数兼容。

高阶函数实现装饰器链,核心在于让每个装饰器都符合“接收函数、返回函数”的规则,再通过顺序调用或 @ 语法叠加,形成执行流从内到外的嵌套结构。
装饰器链的本质是高阶函数的连续应用
每个装饰器本身就是一个高阶函数:它接受一个函数作为参数,返回另一个函数。当多个装饰器叠加时,Python 实际执行的是:
- 最靠近函数的装饰器最先执行(即最内层),处理原始函数
- 其返回的新函数,再作为参数传给上一个装饰器
- 依此类推,形成“函数 → 装饰后函数 → 再装饰后函数”的链式传递
手动构造装饰器链(不依赖 @)
你可以直接用函数调用方式串联多个高阶函数:
- 假设有两个装饰器:
log_calls和measure_time - 写法:
enhanced_func = log_calls(measure_time(original_func)) - 等价于:
@log_calls\n@measure_time\ndef original_func(): ... - 执行顺序:先
measure_time包裹original_func,再用log_calls包裹它返回的结果
使用 @ 语法定义多层装饰器链
在函数上方按从下到上的顺序书写装饰器,逻辑更清晰:
-
@retry(max_attempts=3)→ 最外层,最后执行 -
@log(level='DEBUG')→ 中间层 -
@validate_input→ 最内层,最先执行 - 实际等效于:
func = retry(...)(log(...)(validate_input(original_func)))
关键细节:保持函数元信息和参数兼容性
链中每个装饰器都应做到:
- 内层包装函数用
*args, **kwargs接收任意参数,确保被装饰函数调用方式不变 - 用
@functools.wraps(func)修饰 wrapper,避免链式叠加后__name__、__doc__全变成wrapper - 若某装饰器带参数(如
@cache(ttl=60)),它必须是三层结构,否则无法参与链式组合

















