是初学者。对不起,如果我的问题幼稚。 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可以做到吗?
最佳答案
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__
方法,或者,如果使用更高级的类之一而不是dict,则可以查看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版本中都是可腌制的,因此,这显然是故意的。