这是一个非常简单的缓存装饰器。它不考虑参数的任何变化,它只是在第一次调用后返回相同的结果。那里有更高级的缓存,可以缓存每个输入组合的结果(“记忆”)。
import functools
def callonce(func):
result = []
@functools.wraps(func)
def wrapper(*args, **kwargs):
if not result:
result.append(func(*args, **kwargs))
return result[0]
return wrapper
用法:
@callonce
def long_running_function(x, y, z):
# do something expensive with x, y, and z, producing result
return result
如果您出于某种原因更愿意将函数编写为生成器(可能每次调用的结果略有不同,但初始设置仍然很耗时,或者您只需要允许您的函数的 C 样式静态变量记住从一个调用到下一个调用的一些状态),你可以使用这个装饰器:
import functools
def gen2func(generator):
gen = []
@functools.wraps(generator)
def wrapper(*args, **kwargs):
if not gen:
gen.append(generator(*args, **kwargs))
return next(gen[0])
return wrapper
用法:
@gen2func
def long_running_function_in_generator_form(x, y, z):
# do something expensive with x, y, and z, producing result
while True:
yield result
result += 1 # for example
用于允许将参数传递给生成器的每次迭代的Python 2.5 或更高版本.send()
如下(注意**kwargs
不支持):
import functools
def gen2func(generator):
gen = []
@functools.wraps(generator)
def wrapper(*args):
if not gen:
gen.append(generator(*args))
return next(gen[0])
return gen[0].send(args)
return wrapper
@gen2func
def function_with_static_vars(a, b, c):
# time-consuming initial setup goes here
# also initialize any "static" vars here
while True:
# do something with a, b, c
a, b, c = yield # get next a, b, c