python - 使用函数对象作为字典键

标签 python function caching python-3.x decorator

我使用函数对象作为字典键。我这样做是因为我需要缓存这些函数的结果。这大致是我正在使用的代码:

# module cache.py:
calculation_cache = {}
def cached(func):
  # func takes input as argument
  def new_function(input):
    try:
      result = calculation_cache[(func, input)]
    except KeyError:
      result = func(input)
      calculation_cache[(func, input)] = result
    return result
  return new_function

# module stuff.py
@cached
def func(s):
  # do something time-consuming to s
  # ...
  return result

我可以使用 func.__module__ + func.__name__ 而不是 func,但如果 func 工作正常,我宁愿使用它因为我担心可能的名称冲突(例如,对于 lambda 函数或嵌套函数或被另一个同名函数替换的函数等)

这似乎工作正常,但我怀疑这可能会在某些难以测试的情况下导致问题。

例如,我担心一个函数被以某种方式删除,而另一个函数重用其内存空间。在这种情况下,我的缓存将无效,但它不会知道这一点。这是一个合理的担忧吗?如果是这样,有什么办法可以解决吗?

函数可以删除吗?重新加载模块是否会将函数移动到新地址(从而更改其哈希值,并为新函数释放旧内存地址)?有人(出于某种奇怪的原因)可以简单地删除模块中定义的函数(再次为新函数提供内存)吗?

如果只有使用 def 显式定义的函数才安全,那么我可以禁止使用 cached 除了作为装饰器(我不知道如何强制执行它,但我可以将其记录在缓存文档字符串中)。

最佳答案

我不确定我能否解决您上述的所有问题,但我可以解决其中 1 个 --

我看不出有任何原因导致函数无法被垃圾收集。但是,由于您的函数是字典中的键,因此只要该字典存在,函数的引用计数就永远不会达到零,并且不会受到垃圾回收的影响。

我不知道如何重新加载模块,但是,这似乎是您不需要真正担心的极端情况。模块并不真正意味着要重新加载......事实上,您在某些情况下可以这样做主要是为了在交互式终端中进行调试,而不是为了在任何实际代码中使用...... .(据我所知...)

关于python - 使用函数对象作为字典键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12311711/

相关文章:

python - 在 Python 中检测非英文字符的字符串

python - 如何在 Windows 上优雅地终止 python 进程

python - 如何在 form_valid 中获取对象 ID?

c++ - 更改描述函数行为的位置会导致错误?

asp.net - IE 8 和客户端缓存

python - 通过 OBEX 发送文件(浅蓝色/OBEXFTP)

c++ - 更新 char* 函数 C++

C - 自定义 qsort 不工作

node.js 如何访问已经需要的对象

caching - 如何开始使用 Web 缓存、CDN 和代理服务器?