我们在编码的时候常常有函数计时的需求,通常都是直接使用python自带的time库来实现。
import time
t0 = time.time()
... # 要计时的代码
elapsed = time.time() - t0
print(f"耗时{elapsed}s")
这种方式显然不够优雅。
装饰器很适合用于给函数计时,只需要在函数定义时,函数的上方使用装饰器,就能实现对函数的计时,随用随写。
import time
from functools import wraps
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
t0 = time.time()
result = func(*args, **kwargs)
elapsed = time.time() - t0
print(f"耗时{elapsed}s")
return result
return wrapper
使用时:
@timer
def do_something():
...
do_something() # 执行函数时自动执行装饰器中代码 显示该函数的耗时
装饰器的好处是对函数本身的代码无侵入,但仅适用于函数的情形,而且如果一个函数上已经有其他装饰器,再叠加装饰器可能会有潜在的问题。此时的另一种方案是使用上下文管理器,配合with
关键字实现计时功能。
创建一个用于计时的上下文管理器:
import time
class Timer:
# 该函数在进入上下文管理时执行
def __enter__(self):
self.start = time.time()
return self
# 该函数在结束上下文管理时执行
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.time()
self.interval = self.end - self.start # 记录了上下文执行的耗时
def __str__(self):
return str(self.interval)
@property # 该装饰器使得该方法能像作为属性被调用
def str(self):
return self.__str__()
使用时:
with Timer() as elapsed:
... # 要计时的代码
print(f"耗时{elapsed}s")
# 或者使用.str
print(elapsed.str)