python3中的装饰器介绍及其应用场景

python3中的装饰器介绍及其应用场景 目录一、装饰器的本质二、最简单的装饰器示例示例函数执行前后打印日志三、带参数函数的装饰器示例四、使用 functools.wraps重要五、带参数的装饰器高级六、类装饰器七、多个装饰器八、装饰器的常见应用场景1 日志记录2 性能统计3 权限控制4 缓存非常经典5 重试机制6 Web框架最常见九、装饰器在大型项目中的作用十、装饰器执行流程面试经典十一、装饰器结构总结最通用模板十二、一张完整结构图Python3 中的装饰器Decorator是一种非常重要的语法特性本质上是对函数或类进行“包装”的一种机制。它允许你在不修改原函数代码的情况下动态地给函数增加功能。装饰器在Web框架、日志系统、权限控制、缓存、性能统计等场景中非常常见。一、装饰器的本质一句话理解装饰器 接收函数 → 返回新函数 的函数。数学表达decorator(func) - new_func使用装饰器语法decoratordeffoo():pass等价于foodecorator(foo)二、最简单的装饰器示例示例函数执行前后打印日志defdecorator(func):defwrapper():print(函数执行前)func()print(函数执行后)returnwrapperdecoratordefsay_hello():print(Hello)say_hello()输出函数执行前 Hello 函数执行后执行流程say_hello decorator(say_hello) 调用 say_hello() 实际上调用 wrapper()结构图say_hello() ↓ wrapper() ↓ func() (原函数)三、带参数函数的装饰器现实中函数一般都有参数。示例defdecorator(func):defwrapper(*args,**kwargs):print(执行前)resultfunc(*args,**kwargs)print(执行后)returnresultreturnwrapperdecoratordefadd(a,b):returnabprint(add(3,5))输出执行前 执行后 8关键点*args **kwargs保证装饰器可以适用于任何函数。四、使用 functools.wraps重要装饰器会覆盖原函数信息print(add.__name__)会输出wrapper解决方法fromfunctoolsimportwrapsdefdecorator(func):wraps(func)defwrapper(*args,**kwargs):print(执行前)returnfunc(*args,**kwargs)returnwrapper作用保持__name__ __doc__ __module__等元信息。五、带参数的装饰器高级有时候装饰器本身也需要参数。例如retry(3) cache(10) timeout(5)实现结构三层函数示例defrepeat(n):defdecorator(func):defwrapper(*args,**kwargs):foriinrange(n):func(*args,**kwargs)returnwrapperreturndecoratorrepeat(3)defhello():print(hello)hello()输出hello hello hello等价于hello repeat(3)(hello)结构repeat(n) ↓ decorator(func) ↓ wrapper()六、类装饰器装饰器不仅可以装饰函数还可以装饰类。示例defadd_attr(cls):cls.authorTomreturnclsadd_attrclassBook:passprint(Book.author)输出Tom七、多个装饰器ABCdeff():pass执行顺序f A(B(C(f)))调用顺序A wrapper ↓ B wrapper ↓ C wrapper ↓ f八、装饰器的常见应用场景1 日志记录deflog(func):defwrapper(*args,**kwargs):print(f调用函数{func.__name__})returnfunc(*args,**kwargs)returnwrapper常见于Web服务API调用2 性能统计importtimedeftimer(func):defwrapper(*args,**kwargs):starttime.time()resultfunc(*args,**kwargs)print(耗时:,time.time()-start)returnresultreturnwrapper常见算法测试 性能分析3 权限控制例如 Web APIdeflogin_required(func):defwrapper(user):ifnotuser.logged_in:raiseException(请登录)returnfunc(user)returnwrapperFlask / FastAPI 中非常常见。4 缓存非常经典Python 自带functools.lru_cache示例fromfunctoolsimportlru_cachelru_cache(maxsize128)deffib(n):ifn2:returnnreturnfib(n-1)fib(n-2)作用动态规划 缓存计算结果5 重试机制例如网络请求defretry(n):defdecorator(func):defwrapper(*args,**kwargs):for_inrange(n):try:returnfunc(*args,**kwargs)except:passraiseException(失败)returnwrapperreturndecorator6 Web框架最常见例如Flaskapp.route(/home)defhome():returnhelloapp.route就是装饰器。作用URL → 函数映射九、装饰器在大型项目中的作用在大型项目如 AI / Web / 后端中装饰器常用于作用示例日志log decorator缓存lru_cache权限login_required重试retry计时timer注册机制register decorator路由Flask route配置注入Hydra / draccus例如你之前问的draccus里面也经常用装饰器实现配置注册 配置解析十、装饰器执行流程面试经典代码decoratordeff():pass执行顺序1 定义 f 2 执行 decorator(f) 3 返回 wrapper 4 f wrapper 5 调用 f() 实际执行 wrapper()十一、装饰器结构总结最通用模板fromfunctoolsimportwrapsdefdecorator(func):wraps(func)defwrapper(*args,**kwargs):# beforeresultfunc(*args,**kwargs)# afterreturnresultreturnwrapper十二、一张完整结构图decorator def func() ↓ decorator(func) ↓ wrapper ↓ func wrapper ↓ 调用 func() ↓ wrapper() ↓ 原函数