浅谈Python装饰器的体会
这里不做引入分析,即不一步一步将普通函数转化为装饰器的过程,具体可以百度.
下面直接从最简单的装饰器的构建开始.
首先什么是装饰器,现在先不说,后面具体表述.
先提出一个需求 我们要在函数开始执行以及执行完成后分别用日志的形式记录一下.
先定一个获取当前时间字符串的函数.
1 2 | def get_time(): return datetime.now().strftime( '%Y-%m-%d %H:%M:%S' ) |
接下来按照需求,构建一个不带参数的装饰器
1 2 3 4 5 6 7 | def log(func): def wrapper( * args, * * kwargs): print (f '{get_time()} {func.__name__}开始执行' ) res = func( * args, * * kwargs) print (f '{get_time()} {func.__name__}结束执行' ) return res return wrapper |
上面定义好了一个装饰器,作用是是记录开始和结束信息.
下面是被装饰器调'装饰'的函数
1 2 3 4 5 6 | @log def fun(): print ( '开始计时...' ) time.sleep( 3 ) print ( '结束计时...' ) return 123 |
运行起来的结果:
可以看到,在fun函数开始和结束是,均有额外信息的打印,说明第一个需求完成
但是,如果甲方爸爸增加需求,要求根据不同场景传入参数,打印不同的日志信息,此时必须也要把一些参数传入.
以下是成果:
1 2 3 4 5 6 7 8 9 10 | def log_with_params( * param): def log(func): def wrapper( * args, * * kwargs): print (f '{get_time()} {func.__name__}开始执行' ) res = func( * args, * * kwargs) print (f '传入的参数是{param}' ) print (f '{get_time()} {func.__name__}结束执行' ) return res return wrapper return log |
这一次,装饰器多了一层函数,可以具备接收外部参数(而不是被装饰器的函数的参数)功能,还是对同一个函数应用这个装饰器
1 2 3 4 5 6 | @log_with_params ( 'params' ) def fun(): print ( '开始计时...' ) time.sleep( 3 ) print ( '结束计时...' ) return 123 |
再次执行函数:
可以看到外部传入给装饰器的参数已被内部接收到.,基本上大功告成.
但这里还有一个小问题
如果此时打印应用装饰器的函数名称:
很明显,这里应该是fun,而不是warpper,应该是把
内层函数名称打印出来了,为了解决这个问题,在wrapper上应用一个系统定义的装饰器.
此时打印函数fun的名称,恢复了正常
注意这个装饰器使用时需要引入
from functools import wraps
最后以我自己的理解说一下什么是装饰器,对一些函数额外加上一些功能,但又不影响这些函数本身执行过程中定义的一些函数.
当然,类也可以⽤来构建装饰器,这个待笔者学会了再做分析探讨,欢迎大家批评指正
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix