是否有一种方法可以将函数的输出记录到磁盘上?
我有功能
def getHtmlOfUrl(url):
... # expensive computation
并且想做类似的事情:
def getHtmlMemoized(url) = memoizeToFile(getHtmlOfUrl, "file.dat")
然后调用getHtmlMemoized(url),以便每个URL仅进行一次昂贵的计算。
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序列化的数据时。
有关装饰的更多信息:How to make a chain of function decorators?
这是使装饰器在退出时仅保存一次缓存的方法:
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
签出joblib.Memory
。这是一个用于执行此操作的库。
由Python的Shelve模块提供支持的更清洁的解决方案。优点是缓存可以通过众所周知的joblib.Memory
语法进行实时更新,这也是异常证明(无需处理烦人的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
具有用于此的模块。 (您需要Artemis library)
您装饰功能:
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
基本用法:
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]
如果要在使用后将“” cache“写入文件,以后再加载:
your_mem_func = Memoize(your_func)
your_mem_func.load_memo('yourdata.json')
# do your stuff with your_mem_func
假设您的数据是json可序列化的,则此代码应该有效
your_mem_func.save_memo('yournewdata.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
,然后简单地调用它,如果它先前已运行过,您将获得缓存的数据。
已通过python 2.x和python 3.x检查
还有getHtmlOfUrl
。
diskcache
您可以使用cache_to_disk软件包:
diskcache
这会将结果缓存3天,具体取决于参数a,b,c和d。结果存储在您计算机上的pickle文件中,并在下次调用该函数时被取消选中并返回。 3天后,将删除pickle文件,直到重新运行该功能。每当使用新参数调用该函数时,该函数将重新运行。此处更多信息:from diskcache import Cache
cache = Cache("cachedir")
@cache.memoize()
def f(x, y):
print('Running f({}, {})'.format(x, y))
return x, y