目录一、为什么需要“带参数”的装饰器二、带参数装饰器标准结构三、完整示例最经典例子带日志等级四、执行流程非常重要第一步第二步第三步五、带参数装饰器 functools.wraps推荐六、经典应用场景非常重要1 日志控制2 权限控制3 重试机制工程中非常常见4 计时器深度学习训练常用5 参数检查七、进阶带参数 类装饰器八、工程中最常见的写法总结九、一句话总结在 Python 中带参数的装饰器decorator with arguments本质上是三层函数结构。很多人第一次看到会觉得复杂其实理解它的核心思路就很简单装饰器要接收参数 → 就需要再包一层函数。我会从4 个部分详细讲清楚1️⃣ 为什么需要带参数装饰器2️⃣ 标准结构必须掌握3️⃣ 逐步执行流程4️⃣ 常见应用场景实际开发一、为什么需要“带参数”的装饰器普通装饰器deflogger(func):defwrapper(*args,**kwargs):print(函数开始执行)resultfunc(*args,**kwargs)print(函数执行结束)returnresultreturnwrapper使用loggerdefadd(a,b):returnab调用add(1,2)输出函数开始执行 函数执行结束但如果我们希望logger(levelINFO)控制日志等级就需要带参数装饰器。二、带参数装饰器标准结构核心结构三层函数defdecorator(arg1,arg2):defreal_decorator(func):defwrapper(*args,**kwargs):# 扩展逻辑resultfunc(*args,**kwargs)returnresultreturnwrapperreturnreal_decorator层级关系decorator(参数) ↓ real_decorator(func) ↓ wrapper(*args, **kwargs)三、完整示例最经典例子带日志等级deflogger(level):defdecorator(func):defwrapper(*args,**kwargs):print(f[{level}] 函数{func.__name__}开始执行)resultfunc(*args,**kwargs)print(f[{level}] 函数{func.__name__}执行结束)returnresultreturnwrapperreturndecorator使用logger(INFO)defadd(a,b):returnab调用add(1,2)输出[INFO] 函数 add 开始执行 [INFO] 函数 add 执行结束四、执行流程非常重要代码logger(INFO)defadd(a,b):returnabPython 实际执行第一步执行logger(INFO)返回decorator第二步执行decorator(add)返回wrapper此时add wrapper第三步调用add(1,2)实际上执行wrapper(1,2)内部再调用func(1,2)总结流程logger(INFO) 等价于 add logger(INFO)(add)非常重要五、带参数装饰器 functools.wraps推荐如果不加wraps函数信息会丢失add.__name__ wrapper正确写法fromfunctoolsimportwrapsdeflogger(level):defdecorator(func):wraps(func)defwrapper(*args,**kwargs):print(f[{level}]{func.__name__})returnfunc(*args,**kwargs)returnwrapperreturndecorator这样add.__name__ add六、经典应用场景非常重要1 日志控制log(levelDEBUG)deftrain():pass常见于深度学习训练API 调用服务日志2 权限控制Web开发中常见require_role(admin)defdelete_user():pass实现defrequire_role(role):defdecorator(func):defwrapper(user,*args,**kwargs):ifuser.role!role:raisePermissionError(权限不足)returnfunc(user,*args,**kwargs)returnwrapperreturndecorator3 重试机制工程中非常常见例如网络请求retry(times3)defrequest_api():pass实现defretry(times):defdecorator(func):defwrapper(*args,**kwargs):foriinrange(times):try:returnfunc(*args,**kwargs)exceptException:print(fretry{i1})returnwrapperreturndecorator4 计时器深度学习训练常用timer(unitms)deftrain_step():pass实现importtimedeftimer(units):defdecorator(func):defwrapper(*args,**kwargs):starttime.time()resultfunc(*args,**kwargs)endtime.time()tend-startifunitms:t*1000print(ftime:{t:.3f}{unit})returnresultreturnwrapperreturndecorator5 参数检查validate_type(int,int)defadd(a,b):returnab七、进阶带参数 类装饰器有时也用class decoratorclassLogger:def__init__(self,level):self.levelleveldef__call__(self,func):defwrapper(*args,**kwargs):print(self.level)returnfunc(*args,**kwargs)returnwrapper使用Logger(INFO)八、工程中最常见的写法总结标准模板建议记住fromfunctoolsimportwrapsdefdecorator(arg):defreal_decorator(func):wraps(func)defwrapper(*args,**kwargs):# beforeresultfunc(*args,**kwargs)# afterreturnresultreturnwrapperreturnreal_decorator九、一句话总结带参数装饰器本质就是三层函数结构参数层 → 装饰器层 → 包装函数层结构decorator(args) ↓ decorator(func) ↓ wrapper()