【发布时间】:2026-01-23 01:20:04
【问题描述】:
我使用函数对象作为字典键。我这样做是因为我需要缓存这些函数的结果。这大致是我正在使用的代码:
# 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,除非作为装饰器(我不知道如何强制执行它,但我可以记录它在cached 文档字符串中)。
【问题讨论】:
-
python 中的函数和其他所有东西一样都是对象。我怀疑只要您持有对它的引用(作为字典中的键),它就会一直存在。我不确定重新加载会产生什么效果,但我会假设它会创建新的函数对象。
-
是重新加载创建的新对象。
标签: python function caching python-3.x decorator