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

Fra*_*lli 20 python memoization python-3.x

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

编辑1可能的解决方案:我们需要挑选任何类型的可调用

问题酸洗__closure__:

_pickle.PicklingError: Can't pickle <class 'cell'>: attribute lookup builtins.cell failed
Run Code Online (Sandbox Code Playgroud)

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

TypeError: arg 5 (closure) must be tuple
Run Code Online (Sandbox Code Playgroud)

Bak*_*riu 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
Run Code Online (Sandbox Code Playgroud)

然后,您可以将其应用为装饰器:

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

并检索cache:

>>> fibonacci.cache
{(32,): 2178309, (23,): 28657, ... }
Run Code Online (Sandbox Code Playgroud)

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

fibonacci.cache = pickle.load(cache_file_object)
Run Code Online (Sandbox Code Playgroud)

我在python的问题跟踪器中发现了一个功能请求来添加转储/加载lru_cache,但是它没有被接受/实现.也许将来有可能通过这些操作获得内置支持lru_cache.

  • 感谢您提供的代码,我将尝试一下,我认为这可能是一个很好的解决方案。我是功能请求的创建者;)看看日期。 (2认同)
  • 根据具体的用例,可能值得使用 [shelves](https://docs.python.org/3.5/library/shelve.html) 构建缓存,这些基本上是持久的字典。 (2认同)
  • @Nudin您的意思是设置`fibonacci.cache`无效吗?是的,应该是`fibonacci .__ wrapped __。cache = ...`我稍微改变了装饰器,现在应该可以正常工作了。 (2认同)
  • 这不是 LRU 缓存,它会无限增长。 (2认同)

Wil*_*ill 7

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

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


reu*_*ano 6

你可以使用我的图书馆,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
Run Code Online (Sandbox Code Playgroud)