如何在Python中缓存函数的值?

如何在Python中缓存函数的值?,python,caching,memoization,Python,Caching,Memoization,我有一个函数,给定一个参数,它计算一个对应的值并返回它。函数的返回值仅取决于其参数,因此我希望以某种方式缓存(记忆)该值。此外,我还希望能够使缓存的值无效 这似乎是一个共同的需要,所以我试图避免重新发明轮子 我想要的是一个高级的、高度可配置的、高性能的库(工具、框架等),并且希望更改尽可能精简。一些优点是: 有效地处理并发请求 能够使用不同的缓存后端(例如RAM或DB) 保持对大规模数据的响应能力 有哪些好的库可以使用,它们是如何比较的?您可以使用一个简单的内存缓存 缓存函数的一个示例: i

我有一个函数,给定一个参数,它计算一个对应的值并返回它。函数的返回值仅取决于其参数,因此我希望以某种方式缓存(记忆)该值。此外,我还希望能够使缓存的值无效

这似乎是一个共同的需要,所以我试图避免重新发明轮子

我想要的是一个高级的、高度可配置的、高性能的库(工具、框架等),并且希望更改尽可能精简。一些优点是:

  • 有效地处理并发请求
  • 能够使用不同的缓存后端(例如RAM或DB)
  • 保持对大规模数据的响应能力
有哪些好的库可以使用,它们是如何比较的?

您可以使用一个简单的内存缓存

缓存函数的一个示例:

import functools

@functools.lru_cache()
def f(x, y):
    return x+y

print(f(7, 4))
清除特定值的缓存(脏的、脏的hack,因为无法直接访问缓存dict):

您可以使用,一个简单的内存缓存

缓存函数的一个示例:

import functools

@functools.lru_cache()
def f(x, y):
    return x+y

print(f(7, 4))
清除特定值的缓存(脏的、脏的hack,因为无法直接访问缓存dict):


这个问题对我来说没有多大意义。当您开始谈论“高性能”和“并发请求”时,实际上并不是在应用程序中使用Python库——这听起来更像是使用(或构建)某种专用的外部专用服务或守护进程

就我个人而言,我混合使用记忆和“延迟加载”或“延迟”属性来定义缓存获取(和计算)。“lazy-loaded”的意思是,我不总是拉取(或计算)缓存数据,而是创建一个代理对象,该对象具有在第一次访问时从缓存调用get/create函数的所有信息。当涉及到数据库支持的材料时,我还发现分组缓存未命中和合并缓存获取非常有用-这允许我在可能的情况下并行加载(而不是多个串行请求)


dogpile.cache
负责缓存管理(get、set、invalidate),配置为存储在memcached或dbm中(它允许多个后端)。我使用两个轻量级对象(12行?)来处理延迟获取

这个问题对我来说没什么意义。当您开始谈论“高性能”和“并发请求”时,实际上并不是在应用程序中使用Python库——这听起来更像是使用(或构建)某种专用的外部专用服务或守护进程

就我个人而言,我混合使用记忆和“延迟加载”或“延迟”属性来定义缓存获取(和计算)。“lazy-loaded”的意思是,我不总是拉取(或计算)缓存数据,而是创建一个代理对象,该对象具有在第一次访问时从缓存调用get/create函数的所有信息。当涉及到数据库支持的材料时,我还发现分组缓存未命中和合并缓存获取非常有用-这允许我在可能的情况下并行加载(而不是多个串行请求)


dogpile.cache
负责缓存管理(get、set、invalidate),配置为存储在memcached或dbm中(它允许多个后端)。我使用两个轻量级对象(12行?)来处理延迟获取

如果缓存值仅取决于输入参数,您会在什么情况下使其无效?@Daenyth Cache invalization将仅在需要时执行(以防管理员明确要求重新计算该值)@JakubM。我要求一个更高级的库或框架。性能很重要,我希望避免NIH综合症(即使用可用的库和框架),并希望更改尽可能精简(编辑为提问以反映需求)@JanneKarila我想要的是一个高级可配置的高性能(可能基于某些DB)解决方案。请停止提醒我应该如何使用decorators好吗?如果缓存值仅取决于输入参数,在什么情况下会使其无效?@Daenyth Cache invalidate将仅在需要时执行(以防管理员明确要求重新计算该值)@JakubM。我要求一个更高级的库或框架。性能很重要,我希望避免NIH综合症(即使用可用的库和框架),并希望更改尽可能精简(编辑为提问以反映需求)@JanneKarila我想要的是一个高级可配置的高性能(可能基于某些DB)解决方案。你能不能别再提醒我该如何使用装饰器了?我在寻找一个高级的解决方案,而不仅仅是一个解决方案。请阅读关于这个问题的评论。@ChrisJohnson我的问题很清楚,并且有实际应用。我不接受无法使用的答案并不意味着我拒绝这样做。我在寻找一个高级解决方案,而不仅仅是一个解决方案。请阅读关于这个问题的评论。@ChrisJohnson我的问题很清楚,并且有实际应用。我不接受无法使用的答案并不意味着我拒绝这样做。
f.cache_clear()
def clear_cache_value(cached_function, *args, **kwargs):
    cache = next(c.cell_contents for c in cached_function.cache_info.__closure__ if isinstance(c.cell_contents, dict))
    del cache[functools._make_key(args, kwargs, False)]

clear_cache_value(f, 7, 4)