seg*_*uso 26 python memoization
有没有办法将函数的输出记忆到磁盘?
我有一个功能
def getHtmlOfUrl(url):
... # expensive computation
Run Code Online (Sandbox Code Playgroud)
并希望做类似的事情:
def getHtmlMemoized(url) = memoizeToFile(getHtmlOfUrl, "file.dat")
Run Code Online (Sandbox Code Playgroud)
然后调用getHtmlMemoized(url),以便为每个url只执行一次昂贵的计算.
geo*_*org 27
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
Run Code Online (Sandbox Code Playgroud)
一旦你有了这个,使用@ -syntax"装饰"这个功能就可以了.
@persist_to_file('cache.dat')
def html_of_url(url):
your function code...
Run Code Online (Sandbox Code Playgroud)
请注意,此装饰器是有意简化的,可能不适用于所有情况,例如,当源函数接受或返回无法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
Run Code Online (Sandbox Code Playgroud)
Wil*_*ill 20
退房joblib.Memory
.这是一个完全正确的库.
C. *_*oli 12
还有diskcache
。
from diskcache import Cache
cache = Cache("cachedir")
@cache.memoize()
def f(x, y):
print('Running f({}, {})'.format(x, y))
return x, y
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
在内部,它根据输入参数生成哈希值,并通过该哈希值保存备忘录文件。
看看卡奇尔。它支持额外的缓存配置参数,如 TTL 等。
简单的例子:
from cachier import cachier
import datetime
@cachier(stale_after=datetime.timedelta(days=3))
def foo(arg1, arg2):
"""foo now has a persistent cache, trigerring recalculation for values stored more than 3 days."""
return {'arg1': arg1, 'arg2': arg2}
Run Code Online (Sandbox Code Playgroud)
由Python的Shelve模块提供支持的更清洁的解决方案。优点是缓存可以通过众所周知的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
Run Code Online (Sandbox Code Playgroud)
这将使函数仅被计算一次。下一个后续调用将返回存储的结果。
归档时间: |
|
查看次数: |
10787 次 |
最近记录: |