硬盘LRU缓存Python实现

4
我想要像使用functools.lru_cache一样装饰一个函数,但是我希望结果被缓存到硬盘而不是内存中。我搜索了一下,感觉这个问题已经有解决方案了,所以我想知道是否有人能够指导我(或者至少给我更多的关键词来尝试搜索)。我不知道这是否有帮助或者是否重要,但是这个函数正在计算唯一文件名对应的图像。
1个回答

3
以下是一些代码可供参考:
from pathlib import Path
import pickle
import hashlib
import os

class LRU_Cache:

    def __init__(self, directory, original_function, maxsize=10):
        self.directory = directory
        self.original_function = original_function
        self.maxsize = maxsize
        try:
            os.mkdir(directory)
        except OSError:
            pass

    def __call__(self, *args):
        filename = hashlib.sha1(pickle.dumps(args)).hexdigest()
        fullname = os.path.join(self.directory, filename)
        try:
            with open(fullname, 'rb') as f:
                value = pickle.load(f)
            Path(fullname).touch()
            return value
        except FileNotFoundError:
            pass
        value = self.original_function(*args)
        with open(fullname, 'wb') as f:
            pickle.dump(value, f)
        filenames = os.listdir(self.directory)
        if len(filenames) <= self.maxsize:
            return
        fullnames = [os.path.join(self.directory, filename)
                     for filename in filenames]
        oldest = min(fullnames, key=lambda fn: os.stat(fn).st_mtime)
        os.remove(oldest)

它使用哈希处理参数以创建每个函数调用的唯一文件名。函数返回值使用该文件名进行pickling。
缓存命中会取消存储的结果并更新文件修改时间。
如果缓存目录超过目标大小,最旧的缓存文件将被删除。
这样使用它:
def square(x):
    print('!')
    return x ** 2

sqr = LRU_Cache('square_cache', square, 10)

现在正常调用sqr,结果将被缓存到磁盘。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接