题
我希望建立该给定的函数将缓存功能,以在装修中指定的位置的结果的高速缓存装饰器。是这样的:
@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')
实际上要调用与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
保罗的回答是不错的,我想移动缓存对象,因此并不需要建立每次和设计缓存,这样,它会引发KeyError异常时,有一个高速缓存未命中:
def cache(filepath): def decorator(f): f._cache = Cache(cachepath) def decorated(*args,**kwargs): try: key = (args, kwargs) res = f._cache.get(key) except KeyError: res = f(*args, **kwargs) f._cache.put(key, res) return res return decorated return decorator
不隶属于 StackOverflow