缓存装饰器
缓存装饰器与参数检查十分相似,不过它重点是关注那些内部状态不会影响输出的函数。每组参数都可以链接到唯一的结果。这种编程风格是函数式编程的特点,当输入值有限时可以使用。
因此,缓存装饰器可以将输出与计算它所需要的参数放在一起,并在后续的调用中直接返回它。这种行为被称为memoizing。
例子
我们下面创建一个使用装饰器缓存技术,实现记录在一定时间内函数是否被调用的例子,来解释装饰器用于缓存的用法。
准备工作
首先我们准备引入相关的包,time用于获取当前时间,hashlib用于转换成哈希值,pickle用于将多个参数打包成一个对象,cache变量代表的是对函数返回值和时间的缓存。
import time
import hashlib
import pickle
cache = {}
依赖函数
def is_obsolete(entry, duration):
return time.time() - entry['time'] > duration
def compute_key(function, args, kw):
key = pickle.dumps((function.__name__, args, kw))
return hashlib.sha1(key).hexdigest()
is_obsolete函数是用来比较上次函数访问时间(entry[‘time’],entry是一个字典,entry[‘time’]存储的就是上次访问的时间)与当前时间(time.time())的间隔是否大于指定间隔(duration)的函数。
compute_key函数将传入的function,args,kw打包并转换成二进制形式,作为函数与参数对应的唯一标识。
构建修饰器
def memoize(duration=10):
def _memoize(function):
def __memoize(*args, **kw):
key = compute_key(function, args, kw)
# 是否已经拥有它了?
if (key in cache and
not is_obsolete(cache[key], duration)):
print('we got a winner')
return cache[key]['value']
# 计算
result = function(*args, **kw)
# 保存结果
cache[key] = {
'value': result,
'time': time.time()
}
return result
return __memoize
return _memoize
在__memoize函数中,先使用compute_key函数获取十六进制的哈希值,作为唯一关键词。然后查询是否存在于缓存中(cache)并且时间是否满足条件,如果均满足则直接返回上次的运行结果。否则重新计算结果并将结果存入缓存(cache)后返回。
测试
我们首先创建一个实现加法运算的函数
@memoize()
def add(a, b):
# 如果在执行这个计算时计算机过热
# 请考虑中止程序
return a + b
如果我们用以下代码测试
print(add(1, 2))
print(add(1, 2))
print(add(2, 2))
得到的运行结果如下:
3
we got a winner
3
4
第二次调用add(1, 2)时因为前面已经调用过了,所以就直接给出提示返回结果,而add(2, 2)是一个新的参数的运算,所以进行了再次重复的运算。
下面我们来看一下如果超时会有怎样的结果,由于默认的menoize参数是10,所以我们这里改成1文章来源:https://www.toymoban.com/news/detail-822693.html
@memoize(1) # 1秒后令缓存失效
def add(a, b):
return a + b
print(add(2, 3))
time.sleep(2)
print(add(2, 3))
我们使用time.sleep沉睡两秒
运行结果是文章来源地址https://www.toymoban.com/news/detail-822693.html
5
5
到了这里,关于Python高级用法:装饰器用于缓存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!