有些函数由于计算量较大等原因,可能会造成速度慢的问题,对于一些给定参数的返回值,如果将其存储起来,下次调用时直接从存储结果中读取函数返回值,那么将会节约大量时间,本文将介绍这样一种存储函数返回值的装饰器,已节省频繁使用相同参数调用函数的时间。
第一步,写一个计算函数执行时间的装饰器:
import time def deco_time(func): def wrap(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) stop_time = time.time() print "used time:" + str(stop_time - start_time) return result return wrap
第二步,写一个阶乘函数,并调用上面的时间装饰器:
@deco_time def fac(n): result = 1 for i in range(1, n+1): result *= i time.sleep(0.5) #为了延长函数执行时间,此处睡0.5秒 return result print fac(10)
执行结果如下:
used time:5.00699996948
3628800
第三步,写一个存储函数返回值的装饰器,新建一个字典dict用来存储函数的返回值,以传入的参数作为字典的键。
由于涉及到函数的位置参数和关键字参数,为遵循字典键的不可变性,此处将包含位置参数和关键字参数的元组转换成字符串作为字典的键,每一次调用函数时,先检查传入的参数是否为字典的键,如果是,直接返回该键对应的值,否则,执行函数,并将参数作为键,返回值作为值传入字典以便今后使用:
dict = {} def deco_result(func): def wrap(*args, **kwargs): str_args = str((args, kwargs)) if str_args in dict: result = dict[str_args] else: result = func(*args, **kwargs) dict[str_args] = result return result return wrap
第四步,再次调用fac函数并加上deco_result装饰器,输出dict:
@deco_time @deco_result def fac(n): result = 1 for i in range(1, n+1): result *= i time.sleep(0.5) #为了延长函数执行时间,此处睡0.5秒 return result print fac(10) print fac(5) print fac(3) print fac(10) print dict
结果如下:
可以看到第二次执行fac(10),时间明显少于第一次。输出字典,可以看到被保存的参数以及返回值。下次遇到相同参数的函数调用,就可以直接从字典中输出返回值,可节约函数的执行时间。