是个初学者。对不起,如果我的问题很幼稚。 python中的cachetools是否可用于后续运行?
import cachetools
import time
@cachetools.cached({})
def find_sum(n):
time.sleep(5)
return n+2
print find_sum(2)
print find_sum(3)
print find_sum(2)
因此,在第一次运行期间,第三次调用的速度更快,但是在下次运行文件时,我希望第一次调用更快,并从缓存中获取结果。 cachetools可以做到吗?
答案 0 :(得分:2)
cachetools
无法做到这一点。但这很容易添加。
您可以将所需的任何可变映射传递到memoizing decorators。您使用的是普通的老字典,而字典对泡菜来说却微不足道。而且,即使您使用了库提供的cache implementations之一,它们也很容易被腌制。 1
所以:
import cachetools
import pickle
import time
try:
with open('mycache.pickle', 'rb') as f:
cache = pickle.load(f)
except FileNotFoundError:
cache = {} # or cachetools.LRUCache(maxsize=5) or whatever you want
@cachetools.cached(cache)
def find_sum(n):
time.sleep(5)
return n+2
print(find_sum(2))
print(find_sum(3))
print(find_sum(2))
with open('mycache.pickle', 'wb') as f:
pickle.dump(cache, f)
您当然可以添加:
finally
或上下文管理器或atexit
来确保即使遇到异常或^ C也可以在关闭时保存文件。__setitem__
方法,或者,如果使用更高级的类之一而不是字典,则可以查看Extending cache classes,以进行其他操作。)或者您甚至可以使用磁盘键值数据库作为缓存。
最简单的数据库是dbm
。键和值均限制为str
/ bytes
。 (如果要使用非字符串值,则可以使用shelve
;如果要使用非字符串键,则可能需要其他解决方案。)因此,对于我们的示例而言,这不太可行。但是对于类似的例子,这几乎是魔术:
import dbm
import time
import cachetools
cache = dbm.open('mycache.dbm', 'c')
@cachetools.cached(cache, key=lambda s:s)
def find_string_sum(s):
time.sleep(5)
return s + '!'
print(find_string_sum('a'))
print(find_string_sum('b'))
print(find_string_sum('a'))
唯一棘手的一点是我必须重写key
函数。 (默认键函数处理*args, **kw
,因此对于参数'a'
,您最终会得到类似(('a',), ())
的名称,这显然不是字符串。)
1。正如您从the source中所看到的那样,已进行了一些错误修复,以确保所有类在所有受支持的Python版本中都是可腌制的,因此,这显然是故意的。