用于python中后续运行的Cachetools

时间:2018-06-21 07:19:30

标签: python caching

是个初学者。对不起,如果我的问题很幼稚。 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可以做到吗?

1 个答案:

答案 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也可以在关闭时保存文件。
  • 一个定时保存它们的计时器。
  • 高速缓存对象上的钩子,用于保存每次更新或每N次更新。 (只需重写__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版本中都是可腌制的,因此,这显然是故意的。