很多人学装饰器只记住了 @ 语法糖,却说不清它解决什么痛点。
本质:装饰器是一个「接收函数、返回函数」的高阶函数,用来给已有函数无侵入地加功能——日志、计时、鉴权、缓存都属此类。
import time, functools
def timer(fn):
@functools.wraps(fn) # 保留原函数的名字/文档
def wrap(*a, **k):
t = time.time()
r = fn(*a, **k)
print(f"{fn.__name__} 耗时 {time.time()-t:.3f}s")
return r
return wrap
@timer
def work():
time.sleep(0.1)
几个关键点:
1. 一定要用 functools.wraps,否则被装饰函数的 __name__、__doc__ 会丢失,出 bug 时堆栈很难看。
2. 带参装饰器就是「三层嵌套」:def deco(arg): def deco2(fn): ...,外层收参数、内层收函数。
3. 类也能当装饰器(实现 __call__),适合需要保存状态的场景,比如限流计数器。
我论坛里发的「接口限流中间件」那帖就是用装饰器思路做的,可以对照看。
楼主 · 2026-09-27 12:22 · 浏览 236
· 编辑于 2026-09-27 12:22

