@wraps 修饰器:让你的 Python 代码更加简短可爱 | 从简单实例来认识它
Posted 小拍Piper
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了@wraps 修饰器:让你的 Python 代码更加简短可爱 | 从简单实例来认识它相关的知识,希望对你有一定的参考价值。
@wraps 修饰器:让你的 Python 代码更加简短可爱 | 从简单实例来认识它
我们在上一篇文章(Python实例来认识并发与并行)中用到了 @timer
,在函数定义时,加上一个小小的 @timer
,这样,函数执行结束后,就会自动在控制台汇报自己运行的时间。
比如下面这样:
@timer
def piper():
for i in range(10000):
i = i * i ** 10
piper()
输出:
timer: using 0.00600 s
实际上,这个计时器逻辑 @timer
是我们自己用 Python 中的修饰器特性来实现的。
拆解逻辑
其实我们不用修饰器,自己也能实现计时的逻辑。
def piper():
for i in range(10000):
i = i * i ** 10
t = time.time() # 记录函数开始时时间
piper()
print(f"timer: using {time.time() - t :.5f} s") # 获取函数运行时间并打印
注意到我们执行函数时,在其上下都包裹上了逻辑。如果我们希望函数自带计时逻辑,那么为了包住原函数,只能去新定义一个函数。
def time_wrapper(func):
# func 是一个函数
t = time.time()
func()
print(f"timer: using {time.time() - t :.5f} s")
time_wrapper(piper)
输出:
timer: using 0.00600 s
我们想测试某一个函数运行时间时,将函数名输入到 time_wrapper
里面就好。
更优雅的改进
上述代码显然有缺点:
- 我们在编程时,心智负担增大了;此外,代码更冗长了
- 如果我们只是希望函数新增一个功能,显然用
time_wrapper
是不行的,因为其并没有改变piper
本身
于是我们请出今天的主角 修饰器@wraps 。
还用我们的 timer
举例子,我们让所有在 @timer
下的函数,都经过如下处理:
def timer(func):
@wraps(func)
def inner_func():
t = time.time()
rts = func()
print(f"timer: using {time.time() - t :.5f} s")
return rts
return inner_func
以 piper
为例,我们经历了如下变化。
@timer
def 原始piper():
for i in range(10000):
i = i * i ** 10
实际上,当你再调用 piper
时,你的 piper
内部逻辑早已变为:
def 当前piper():
t = time.time()
rts = 原始piper()
print(f"timer: using {time.time() - t :.5f} s")
return rts
总结
本文简单与读者朋友们「科普」一下修饰器,注意到我们这里实际上仅仅修饰了无参数的函数。其实,修饰器还有许多更加优雅用途,比如传入参数 *args, **kwargs
,修饰类 __call__
等用法。期待以后我遇到好的应用场景,将经验分享给朋友们。
记得点个『在看』!
我是小拍,关注我!
以上是关于@wraps 修饰器:让你的 Python 代码更加简短可爱 | 从简单实例来认识它的主要内容,如果未能解决你的问题,请参考以下文章
比 requests 更强大 Python 库,让你的爬虫效率提高一倍!
比 requests 更强大 Python 库,让你的爬虫效率提高一倍