装饰器本质是高阶函数:接收函数为参数并返回新函数;不带参装饰器为两层闭包,带参则需三层嵌套实现“装饰器工厂”;functools.wraps用于保留原函数元信息。

装饰器本质是高阶函数
Python装饰器不是语法糖的魔术,而是高阶函数的自然应用:它接收一个函数作为参数,返回一个新的函数(或可调用对象)。关键在于,被装饰的函数本身被传入装饰器,装饰器对其增强后返回替代品,原函数名随后指向这个新函数。
最简装饰器长这样
不带参数的装饰器就是一个接受函数、返回函数的闭包:
def my_decorator(func):
def wrapper(*args, **kwargs):
print("调用前")
result = func(*args, **kwargs)
print("调用后")
return result
return wrapper
使用时:
@my_decorator
def say_hello():
print("hello")
等价于 say_hello = my_decorator(say_hello) —— 这就是高阶函数调用的直接体现。
立即学习“Python免费学习笔记(深入)”;
带参数的装饰器需多嵌套一层
当装饰器需要接收配置参数(如 @retry(times=3)),实际结构是“装饰器工厂”:
- 最外层函数接收装饰器参数,返回真正的装饰器(即高阶函数)
- 中间层才是接收被装饰函数的高阶函数
- 最内层是执行逻辑的 wrapper
这种三层嵌套正是为了满足 @decorator(arg) 语法要求:Python 先执行 decorator(arg) 得到一个可调用对象,再把它作用于目标函数。
functools.wraps 解决元信息丢失问题
直接返回 wrapper 会导致被装饰函数的 __name__、__doc__ 等变成 wrapper 的信息。这是因为 wrapper 是新函数,与原函数无关。
解决方法是在 wrapper 上加 @functools.wraps(func),它会自动将原函数的元信息复制到 wrapper 上。本质上,wraps 是一个预设了 __wrapped__ 属性的装饰器,让调试和反射更可靠。










