@wraps装饰器:让你的Python代码更短更可爱|从一个简单的例子Python例子了解并发和并行)使用了@timer,在定义函数的时候加了一个小的@timer,这样函数执行完后,会自动上报其运行时间控制台。比如下面这样:@timerdefpiper():foriinrange(10000):i=i*i**10piper()output:timer:using0.00600s其实这个定时器逻辑@timer是我们自己用的在Python中实现了装饰器特性。拆解逻辑其实我们不需要装饰器,我们可以自己实现时序逻辑。defpiper():foriinrange(10000):i=i*i**10t=time.time()#记录函数启动的时间piper()print(f"timer:using{time.time()-t:.5f}s")#获取函数的运行时间并打印它以注意当我们执行函数时,逻辑被包裹在上面和下面。如果我们想让函数有自己的时序逻辑,那么为了覆盖原来的函数,只能定义一个新的函数。deftime_wrapper(func):#func是一个函数t=time.time()func()print(f"timer:using{time.time()-t:.5f}s")time_wrapper(piper)output:timer:using0.00600s当我们要测试某个函数的运行时间时,只需将函数名输入time_wrapper即可。更优雅的改进上面的代码显然有缺点:我们在编程的时候,增加了我们的精神负担;另外,代码比较冗长如果我们只是想在函数中添加一个新的函数,显然不能使用time_wrapper,因为它不会改变piper所以请来今天的主角修饰符@wraps。同样以我们的timer为例,我们让@timer下的所有函数都这样处理:deftimer(func):@wraps(func)definner_func():t=time.time()rts=func()print(f"timer:using{time.time()-t:.5f}s")returnrtsreturninner_func以piper为例,我们经历了如下变化。@timerdeforiginalpiper():foriinrange(10000):i=i*i**10事实上,当你再次调用piper时,你的piper内部逻辑已经发生了变化:defcurrentpiper():t=time.time()rts=originalpiper()print(f"timer:using{time.time()-t:.5f}s")returnrts对我们来说,我们实际上只是修改了没有参数的函数。其实装饰器还有很多更优雅的用法,比如传入参数*args,**kwargs,修饰__call__等用法。期待未来能遇到好的应用场景,与朋友分享我的经验。记得点击“在看”哦!我是小派,关注我!
