memoize的磁盘 - 蟒蛇 - 永久记忆化(memoize to disk - python -

2019-09-02 09:52发布

有没有一种方法,以memoize的功能到磁盘的输出?

我有一个函数

def getHtmlOfUrl(url):
    ... # expensive computation

并愿做这样的事情:

def getHtmlMemoized(url) = memoizeToFile(getHtmlOfUrl, "file.dat")

然后调用getHtmlMemoized(URL),以便为每个URL做昂贵的计算一次。

Answer 1:

python提供了非常优雅的方式来做到这一点 - 装饰。 基本上,一个装饰是包装另一个功能而不改变功能的源代码提供附加功能的功能。 你的装饰可以这样写:

import json

def persist_to_file(file_name):

    def decorator(original_func):

        try:
            cache = json.load(open(file_name, 'r'))
        except (IOError, ValueError):
            cache = {}

        def new_func(param):
            if param not in cache:
                cache[param] = original_func(param)
                json.dump(cache, open(file_name, 'w'))
            return cache[param]

        return new_func

    return decorator

一旦你得到了,“装饰”功能使用@ -syntax,你准备好了。

@persist_to_file('cache.dat')
def html_of_url(url):
    your function code...

请注意,此装饰被有意简化,可能不适用于所有情况,例如,当源函数接受或返回不能JSON序列化的数据。

更多关于装饰: 如何使功能装饰链?

下面是如何使装饰保存缓存只有一次,在退出时间:

import json, atexit

def persist_to_file(file_name):

    try:
        cache = json.load(open(file_name, 'r'))
    except (IOError, ValueError):
        cache = {}

    atexit.register(lambda: json.dump(cache, open(file_name, 'w')))

    def decorator(func):
        def new_func(param):
            if param not in cache:
                cache[param] = func(param)
            return cache[param]
        return new_func

    return decorator


Answer 2:

退房joblib.Memory 。 这正是出于这个做一个图书馆。



Answer 3:

一个清洁的解决方案搭载Python的搁置模块。 其优点是通过缓存知名实时得到更新dict语法,也很例外证明(无需处理烦人KeyError )。

import shelve
def shelve_it(file_name):
    d = shelve.open(file_name)

    def decorator(func):
        def new_func(param):
            if param not in d:
                d[param] = func(param)
            return d[param]

        return new_func

    return decorator

@shelve_it('cache.shelve')
def expensive_funcion(param):
    pass

这将有利于将只计算一次的功能。 接下来的后续调用将返回存储的结果。



Answer 4:

像这样的东西应该做的:

import json

class Memoize(object):
    def __init__(self, func):
        self.func = func
        self.memo = {}

    def load_memo(filename):
        with open(filename) as f:
            self.memo.update(json.load(f))

    def save_memo(filename):
        with open(filename, 'w') as f:
            json.dump(self.memo, f)

    def __call__(self, *args):
        if not args in self.memo:
            self.memo[args] = self.func(*args)
        return self.memo[args]

基本用法:

your_mem_func = Memoize(your_func)
your_mem_func.load_memo('yourdata.json')
#  do your stuff with your_mem_func

如果你想使用它后写你的“缓存”的文件-要在未来再次加载:

your_mem_func.save_memo('yournewdata.json')


Answer 5:

假设你的数据JSON序列化,这个代码应工作

import os, json

def json_file(fname):
    def decorator(function):
        def wrapper(*args, **kwargs):
            if os.path.isfile(fname):
                with open(fname, 'r') as f:
                    ret = json.load(f)
            else:
                with open(fname, 'w') as f:
                    ret = function(*args, **kwargs)
                    json.dump(ret, f)
            return ret
        return wrapper
    return decorator

装饰getHtmlOfUrl ,然后简单地调用它,如果它之前已经运行,你会得到你的缓存数据。

经过与Python 2.x和Python 3.x都有



Answer 6:

在Artemis的图书馆有这一个模块。 (你需要pip install artemis-ml

你装饰你的函数:

from artemis.fileman.disk_memoize import memoize_to_disk

@memoize_to_disk
def fcn(a, b, c = None):
    results = ...
    return results

在内部,它使一个哈希出的输入参数,并通过这个散列保存备忘文件。



Answer 7:

您可以使用cache_to_disk包:

    from cache_to_disk import cache_to_disk

    @cache_to_disk(3)
    def my_func(a, b, c, d=None):
        results = ...
        return results

这将缓存结果3天,具体到参数的a,b,c和d。 结果存储在一个文件泡菜您的机器上,和拆封并返回函数被调用下一次。 3天后,咸菜文件被删除,直到功能重新运行。 该功能将被重新运行每当函数调用新的论据。 更多资讯: https://github.com/sarenehan/cache_to_disk



文章来源: memoize to disk - python - persistent memoization