2011-12-08 23 views
6

我一直在寻找一个位的Python模块,提供了一个memoize的装饰具有以下功能:后续的程序运行中重新使用在磁盘上是否有一个建立memoize磁盘装饰器的Python?

  • 存储缓存。
  • 适用于任何pickle-able参数,最重要的是numpy数组。
  • (Bonus)检查参数是否在函数调用中发生了变异。

,我发现了几个小的代码段用于这个任务,很可能实现一个自己,但我宁愿有一个既定的软件包这一任务。我还发现incpy,但这似乎不适用于标准的Python解释器。

理想情况下,我想有类似functools.lru_cache加上磁盘上的缓存存储。有人可以指点我一个合适的包装吗?

回答

2

我不知道任何memoize装饰,照顾所有这一切,但你可能想看看ZODB。它是一个构建于pickle之上的持久性系统,它提供了一些额外的功能,包括在不使用对象时可以将对象从内存移动到磁盘,并且只能保存已修改的对象。

编辑:作为评论的后续行动。 ZODB不支持memoization装饰器。不过,我觉得你可以:

  • 实现自己persistent class
  • 使用在您需要的方法记忆化装饰(任何标准的实施应该工作,但它可能需要进行修改,以确保该dirty bit是设置)

后,如果您创建一个类的对象,并将其添加到ZODB数据库,当你执行的memoized方法之一,该对象将被标记为脏和变化将被保存到数据库在下一个事务提交操作中。

+0

谢谢你的提示。因此,当将数据灵活地存储在内存或磁盘上时,ZODB似乎相当不错。但是在备忘录的背景下会有什么显着的优势? – silvado

+0

所以我想持久化类应该是memoization装饰器被定义的类,并且memoization缓存将是该类的一个属性。我会在不久的将来尝试这个... – silvado

2

我意识到这是一个2岁的问题,这将不能算作一种“既定”的装饰,但是...

这是很简单的,你真的不需要担心只使用已建立的代码。该模块的docs链接到source,因为除了本身有用之外,它还可以用作示例代码。

那么,你需要添加什么?添加一个filename参数。在运行时,pickle.load的文件名放入cache,如果失败则使用{}。将只有pickle.save的缓存添加到cache_save函数中。将该功能附加到wrapper与现有的功能相同(cache_info等)。

如果你想自动保存缓存,而不是把它留给调用者,那很简单;这只是时间问题。你拿出与 - atexit.register任何选项,添加save_every参数,所以它可以节省每save_every失误,... -is微不足道的实施。在this answer我展示了它需要多少工作。或者你可以得到一个完整的工作版本(要定制,或按原样使用)on GitHub

还有其他方法可以扩展它 - 在cache_info中放置一些与保存相关的统计信息(上次保存时间,点击和未命中......),复制缓存并将其保存在后台线程中而不是保存它内联,等等。但我想不出任何值得做的事情,这不是件容易的事。