我正在寻找一种方法来创建一个装饰器以具有一个函数参数,该函数参数实际上使用一个传递给它的包装函数的变量。
例如,假设我有
@cache_decorator("my_key_{}".format(foo))
def my_function(foo, bar):
pass
@cache_decorator("another_key_{}_{}".format(foo, bar)
def another_function(user, foo, bar):
pass
目标是编写一个缓存包装器。装饰器将需要缓存键,但键将包含传递给函数的变量,并且对于它包装的每个函数都不同。
理想情况下,这让装饰器检查给定键的缓存值,如果找不到,则执行函数以获取值并缓存它。这样,如果该值在缓存中,则它不会执行创建该值的代码(即 my_function)。如果未找到,则执行 my_function 并将结果存储在缓存中并返回它。
另一种选择是类似于块的东西:
def my_function(foo, bar):
cache_value("my_key_{}".format(foo),{block of code to generate value that is only called if necessary})
在 Objective-C 或 js 中,这将是一个块,因此我可以保持本地定义和可变的值生成,但仅在必要时执行。我对 python 太陌生,无法完全掌握如何使用它的闭包版本来做到这一点。
谢谢!
更新
虽然下面的解决方案适用于装饰器,但我最终选择了类似块的路线,因为附加到每个缓存条目需要额外的元数据以确保它可以正确失效。使用值生成(而不是在缓存函数内部)定义此元数据更易于维护。这看起来像:
def my_function(foo, bar):
def value_func():
return code_to_generate_value_using_foo_bar
return get_set_cache(key, value_func, ...)
def get_set_cache(key, value_function, ...):
value = cache.get(key)
if value is None:
value = value_function()
cache.set(key, value)
return value