@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__
等用法。期待当前我遇到好的利用场景,将教训分享给敌人们。
记得点个『在看』!
我是小拍,关注我!