
装饰器本质是“函数的函数”
装饰器不是语法糖的魔法,而是 Python 高阶函数特性的自然延伸:它接收一个函数作为参数,返回一个新的函数(或可调用对象)。核心在于闭包 + 函数对象可传递 + @ 语法糖三者结合。
底层实现分三步走
以最简装饰器为例,拆解执行逻辑:
-
定义阶段:写好装饰器函数(如
def timer(func):),它本身不执行被修饰函数,只准备“包装逻辑” -
应用阶段:@timer 写在目标函数上方,等价于
func = timer(func)—— 此时 timer 被立即调用,传入原函数,返回新函数并重新赋值给 func 名字 - 调用阶段:后续调用 func(),实际执行的是装饰器内部返回的那个新函数(通常内部会调用原函数,也可能不调)
面试回答可这样说(简洁版)
“Python 装饰器本质是一个接受函数为参数、返回新函数的高阶函数。它利用闭包保存原函数和额外逻辑,通过 @ 语法糖完成函数替换。关键点有三个:一是函数可作为对象传递;二是嵌套函数能访问外部作用域变量;三是装饰器在模块加载时就完成替换,不是在每次调用时才生效。常见用途包括日志、权限校验、缓存、性能统计等。”
带参数的装饰器要多一层封装
如果装饰器需要接收配置(比如 @retry(max_times=3)),就必须再套一层函数:
立即学习“Python免费学习笔记(深入)”;
- 最外层接收装饰器参数(如 max_times),返回真正的装饰器函数
- 中间层接收被修饰函数,返回包装后的新函数
- 最内层是实际执行逻辑,可使用外层传入的参数和原函数
这种三层结构常被称作“装饰器工厂”,本质仍是函数返回函数。
类装饰器靠 __call__ 实现
用类实现装饰器时,类需定义 __call__ 方法。实例化后该对象可被调用,符合“可调用对象”要求。优势在于能用实例属性保存状态(比如统计调用次数),比函数装饰器更易管理上下文。










