保存和加载到缓存的是源对象变换后的版本。
项目描述
flexcache
一个强大且可扩展的包,用于在磁盘上缓存昂贵计算的结果。
考虑一个昂贵的函数 parse,它接受一个路径并返回一个解析版本
>>> content = parse("source.txt")
将这个结果自动和持久地缓存起来会很好,这就是flexcache的用武之地。
首先,我们创建一个 DiskCache 对象
>>> from flexcache import DiskCacheByMTime
>>> dc = DiskCacheByMTime(cache_folder="/my/cache/folder")
然后加载
>>> content, basename = dc.load("source.txt", converter=parse)
如果这是第一次调用,由于缓存的结果不可用,parse 将在 source.txt 上调用,并将输出保存并返回。下次调用时,将加载缓存并返回。
当源文件改变时,DiskCache 会检测到缓存的文件较旧,再次调用 parse 并存储并返回新结果。
在某些情况下,您可能希望通过哈希文件来检测文件是否已更改。只需使用 DiskCacheByHash 而不是 DiskCacheByMTime。
缓存文件使用pickle协议保存,每个文件都有一个包含标题内容的伴随json文件。
这个想法是完全灵活的,不仅适用于解析器。在 flexcache 中,我们说有两种类型的对象:源对象 和 转换对象。转换函数将前者映射到后者。缓存通过查看前者可定制的方面来存储后者。
构建自己的缓存逻辑
在某些情况下,您可能希望自定义缓存和失效的处理方式。
您可以通过继承 DiskCache 来实现这一点。
>>> from flexcache import DiskCache
>>> class MyDiskCache(DiskCache):
...
... @dataclass(frozen=True)
... class MyHeader(NameByPathHeader, InvalidateByExist, BasicPythonHeader):
... pass
...
... _header_classes = {pathlib.Path: MyHeader}
在这里,我们创建了一个自定义的 Header 类,并使用它来处理 pathlib.Path 对象。您甚至可以在同一个类中注册多个头部,以处理不同类型的源对象。
我们提供了一组方便的可混合类,以实现几乎所有行为。这些类分为三个类别,您必须从每个类别中选择至少一个。
头部
这些类存储将随缓存文件一起保存的信息。
BaseHeader:源对象和转换函数的标识符。
BasicPythonHeader:源对象、转换函数标识符、平台、Python 实现和 Python 版本。
失效
这些类定义了缓存如何决定缓存的转换对象是否是源对象的实际表示。
InvalidateByExist:缓存文件必须存在。
InvalidateByPathMTime:缓存文件存在且比源对象(必须是 pathlib.Path)更新。
InvalidateByMultiPathsMtime:缓存文件存在且比源对象中的每个路径(必须是 tuple[pathlib.Path])更新。
命名
这些类定义了如何生成名称。缓存文件的基名为由 Header 对象确定的值的集合生成的十六进制散列摘要。
NameByFields:除 source_object 之外的所有字段。
NameByPath:源对象的解析路径(必须是 pathlib.Path)。
NameByMultiPaths:源对象中每个路径的解析路径(必须是 tuple[pathlib.Path]),按升序排序。
NameByFileContent:源对象引用的文件的字节数据(必须是 pathlib.Path)。
NameByHashIter:源对象中的值(必须是 tuple[str]),按升序排序。
NameByObj:源对象的可序列化版本(必须是可序列化的),使用最高可用协议。这还会将 pickle_protocol 添加到头部。
您可以根据需要混合匹配,当然,您也可以创建自己的。
最后,您还可以通过将 _store_header 类属性设置为 False 来避免保存头部。
该项目是 Python 单位包 Pint 的一部分。
请参阅 AUTHORS 以获取维护者列表。
要查看每个项目版本的显著更改的有序列表,请参阅 CHANGES
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。