将缓存存储在Python> = 3.2中的functools.lru_cache文件中

问题描述 投票:20回答:4

我在Python 3.3中使用@functools.lru_cache。我想将缓存保存到文件中,以便在重新启动程序时恢复它。我该怎么办?

编辑1可能的解决方案:We need to pickle any sort of callable

问题酸洗__closure__

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

如果我尝试在没有它的情况下恢复功能,我会得到:

TypeError: arg 5 (closure) must be tuple
python python-3.x memoization
4个回答
19
投票

您无法使用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, ... }

然后,您可以根据需要选择/取消激活缓存并加载:

fibonacci.cache = pickle.load(cache_file_object)

我在python的问题跟踪器中找到了一个feature request来向lru_cache添加转储/加载,但它没有被接受/实现。也许将来有可能通过lru_cache为这些操作提供内置支持。


3
投票

考虑使用joblib.Memory对磁盘进行持久缓存。

由于磁盘很大,因此不需要LRU缓存方案。


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

1
投票

除了公共API之外,您不应该触摸装饰器实现中的任何内容,因此如果您想要更改其行为,您可能需要复制其实现并自己添加必要的功能。请注意,缓存当前存储为循环双向链表,因此在保存和加载时需要注意。

© www.soinside.com 2019 - 2024. All rights reserved.