存储缓存在Python> = 3.2文件functools.lru_cache(Store t

2019-07-22 20:34发布

我使用@functools.lru_cache在Python 3.3。 我想缓存保存到一个文件,以恢复它时,程序将重新启动。 我怎么能这样做?

编辑1个可能的解决方法: 我们需要腌制任何类型的可调用

问题酸洗__closure__

_pickle.PicklingError: Can't pickle <class 'cell'>: attribute lookup builtins.cell failed

如果我尝试恢复该功能没有它,我得到:

TypeError: arg 5 (closure) must be tuple

Answer 1:

你不能做你想要使用的是什么lru_cache ,因为它没有提供一个API来访问缓存,它可能用C在未来版本中被改写。 如果你真的想保存的缓存,你必须使用一个不同的解决方案,让您可以访问缓存。

这是很简单的自己写高速缓存。 例如:

from functools import wraps

def cached(func):
    func.cache = {}
    @wraps(func)
    def wrapper(*args):
        try:
            return func.cache[args]
        except KeyError:
            func.cache[args] = result = func(*args)
            return result   
    return wrapper

然后,您可以将它作为一种装饰:

>>> @cached
... def fibonacci(n):
...     if n < 2:
...             return n
...     return fibonacci(n-1) + fibonacci(n-2)
... 
>>> fibonacci(100)
354224848179261915075L

和检索cache

>>> fibonacci.cache
{(32,): 2178309, (23,): 28657, ... }

然后,您可以泡菜/ unpickle缓存,请你,并加载它:

fibonacci.cache = pickle.load(cache_file_object)

我发现了一个功能要求在巨蟒的问题跟踪器添加转储/负载lru_cache ,但没有被接受/执行。 也许在未来,将有可能对通过这些操作内置支持lru_cache



Answer 2:

考虑使用joblib.Memory持久缓存到磁盘。

由于该盘是巨大的,没有必要为一个LRU缓存方案。



Answer 3:

你可以用我的,库mezmorize

import random
from mezmorize import Cache

cache = Cache(CACHE_TYPE='filesystem', CACHE_DIR='cache')


@cache.memoize()
def add(a, b):
    return a + b + random.randrange(0, 1000)

>>> add(2, 5)
727
>>> add(2, 5)
727


Answer 4:

你不应该触摸装饰里面执行任何东西,除了用于公共API,所以如果你想改变自己的行为,你可能需要复制的执行和自己添加必要的功能。 需要注意的是缓存目前存储为一个循环双向链表,所以你需要保存和载入它时要小心。



文章来源: Store the cache to a file functools.lru_cache in Python >= 3.2