我正在寻找一个缓存装饰器,它给出一个函数将函数的结果缓存到装饰中指定的位置.像这样的东西:
@cacheable('/path/to/cache/file') def my_function(a, b, c): return 'something'
装饰器的参数与它包装的函数的参数完全分开.我已经看了很多例子,但是我还没有完全知道如何做到这一点 - 是否有可能为装饰器提供一个与之无关且不传递给包装函数的参数?
这个想法是你的装饰器是一个返回装饰器的函数.
首先写下你的装饰者,好像你知道你的论证是一个全局变量.让我们说:
-
def decorator(f): def decorated(*args,**kwargs): cache = Cache(cachepath) if cache.iscached(*args,**kwargs): ... else: res = f(*args,**kwargs) cache.store((*args,**kwargs), res) return res return decorated
然后编写一个将cachepath作为arg并返回装饰器的函数.
-
def cache(filepath) def decorator(f): def decorated(*args,**kwargs): cache = Cache(cachepath) if cache.iscached(*args,**kwargs): ... else: res = f(*args,**kwargs) cache.store((*args,**kwargs), res) return res return decorated return decorator
是的.如您所知,装饰器是一种功能.写在表格中时:
def mydecorator(func): def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper @mydecorator def foo(a, b, c): pass
传递给的参数mydecorator
是函数foo
本身.
当装饰器接受一个参数时,该调用@mydecorator('/path/to')
实际上将首先用'/ path/to'调用mydecorator函数.然后调用的结果mydecorator(path)
将被调用以接收函数foo
.您正在有效地定义动态包装函数.
简而言之,您需要另一层装饰器功能.
这是一个有点愚蠢的例子:
def addint(val): def decorator(func): def wrapped(*args, **kwargs): result = func(*args, **kwargs) return result + val return wrapped # returns the decorated function "add_together" return decorator # returns the definition of the decorator "addint" # specifically built to return an extra 5 to the sum @addint(5) def add_together(a, b): return a + b print add_together(1, 2) # prints 8, not 3