
回复
下面的装饰器clock会打印函数的运行时间
# descrbe.py
import time
import functools
def clock(func):
"""this is outer clock function"""
@functools.wraps(func) # --> 4
def clocked(*args, **kwargs): # -- 1
"""this is inner clocked function"""
start_time = time.time()
result = func(*args, **kwargs) # --> 2
time_cost = time.time() - start_time
print(func.__name__ + " func time_cost -> {}".format(time_cost))
return result
return clocked # --> 3
@functools.lru_cache() # --> 5
@clock # --> 6
def fib(n):
"""this is fibonacci function"""
return n if n < 2 else fib(n - 1) + fib(n - 2)
if __name__ == "__main__":
# 如果有 @functools.wraps(func) # --> 4 大多数情况下我们希望的输出是这样的
fib(1) # 输出 fib func time_cost -> 9.5367431640625e-07
print(fib.__name__) # 输出 fib
print(fib.__doc__) # 输出 this is fibonacci function
# 如果没有@functools.wraps(func) # --> 4
fib(1) # 输出 fib func time_cost -> 9.5367431640625e-07
print(fib.__name__) # 输出 clocked
print(fib.__doc__) # 输出 this is inner clocked function
@clock # --> 6
def fib(n):
"""this is fibonacci function"""
return n if n < 2 else fib(n - 1) + fib(n - 2)
等价于
fib = clock(fib)
fib会作为func参数传给clock。然后,clock函数会返回clocked函数,Python解释器在背后会把 clocked赋值给fib。实际上如果我们没有添加@functools.wraps(func),我们在ipython中导入describe进一步观察:
In [1]: import describe
In [2]: describe.fib.__name__
Out[2]: 'clocked'
所以,现在fib保存的是 clocked 函数的引用。自此之后,每次调用 fib(n),执行的都是 clocked(n)。clocked 大致做了下面几件事。
版权声明: 本文为 InfoQ 作者【王坤祥】的原创文章。