装饰器原理、手写装饰器、带参装饰器、装饰器嵌套全解
博客导语
装饰器底层=高阶函数+闭包,遵循开闭原则:不修改原函数代码、不修改调用方式,动态扩展功能。面试必考四大形态:无参、传参兼容、带参装饰器、多层嵌套,同时解决函数签名丢失经典坑。
一、基础无参装饰器(原生手写)
@装饰器是语法糖,等价于func = wrapper(func)
def log_decorator(func): # 内层闭包函数 def inner(*args,**kwargs): print("函数开始执行") ret = func(*args,**kwargs) # 执行原函数 print("函数执行结束") return ret return inner @log_decorator def add(a,b): return a+b add(1,2)二、修复函数签名丢失
直接装饰后add.__name__会变成inner,导致日志、异常栈错乱,必须用wraps修复
from functools import wraps def log_decorator(func): @wraps(func) def inner(*args,**kwargs): ... return inner三、带参数装饰器(三层嵌套)
场景:装饰器需要传入自定义参数,例如自定义日志前缀、超时时间,需要三层函数
def log_prefix(prefix): # 第一层接收装饰器参数 def outer(func): @wraps(func) def inner(): print(f"[{prefix}]函数执行") func() return inner return outer @log_prefix("INFO") def hello(): print("hello")四、装饰器嵌套执行顺序
从上到下装饰,从下到上执行。外层装饰器先包裹内层;执行时内层前置逻辑先运行,外层后置逻辑先运行。
五、生产使用场景
接口权限校验、接口耗时统计、日志埋点、缓存击穿、异常统一捕获
