目前,我使用functools
'lru_cache
来处理我的缓存功能。问题是缓存的大小从来不会增长到足以使用LRU
(由于该函数从不接受参数)。相反,该函数在被调用时会打开一个特定的URL并返回其内容。有没有办法使用生存时间装饰器缓存Python 3.5定义?
有没有一种方法可以指定'生存时间'缓存,在一定时间/特定数量的调用后,它会刷新其缓存?
目前,我使用functools
'lru_cache
来处理我的缓存功能。问题是缓存的大小从来不会增长到足以使用LRU
(由于该函数从不接受参数)。相反,该函数在被调用时会打开一个特定的URL并返回其内容。有没有办法使用生存时间装饰器缓存Python 3.5定义?
有没有一种方法可以指定'生存时间'缓存,在一定时间/特定数量的调用后,它会刷新其缓存?
我不知道一个装饰的,但你可以跟踪你得到的页面和更新的最后一次需要。如果这是一个单线程的应用程序,它可以是简单的
_cached_page = ''
_cached_page_time = 0
def get_page():
global _cached_page, _cached_page_time
now = time.time()
# invalidate in 1 hour
if not _cached_page or now - _cached_page_time > 60 * 60:
_cached_page = get_the_page_here()
_cached_page_time = time.time()
return _cached_page
你也可以在后台使用计时器来使页面老化。您需要使用锁来控制访问,但这也会使缓存在多线程程序中可用。
_cached_page = ''
_cached_page_lock = threading.Lock()
def _invalidate_page():
global _cached_page
with _cached_page_lock:
_cached_page = ''
def get_page():
global _cached_page
with _cached_page_lock:
if not _cached_page:
_cached_page = get_the_page_here()
# invalidate in 1 hour
threading.Timer(60*60, _invalidate_page)
return _cached_page
最后,服务器可能在http头中包含一个Expires: ...
字段。根据服务的写入情况,这可以很好地反映页面可以被缓存多久。
functools.lru_cache
函数接受maxsize
参数,该参数将结果保存到最近的调用maxsize
。
您可以通过调用装饰函数的cache_info
属性来检查该属性。
如果要完全刷新缓存,则应通过计算缓存调用的数量并在缓存达到最大大小时重置缓存来手动实施现金对象。
from functools import wraps
class Mycache(object):
def __init__(self, maxcount):
self.count = 0
self.maxcount = maxcount
self.cache = {}
def __call__(self, func):
@wraps(func)
def wrapped(*args):
self.count += 1
if self.count > self.maxcount:
self.cache = {}
self.count = 0
result = self.cache[args] = func(*args)
else:
try:
result = self.cache[args]
except KeyError:
result = self.cache[args] = func(*args)
return result
return wrapped
演示:
@Mycache(3)
def a(arg):
print("arg is : {}".format(arg))
return arg ** 2
print(a(4))
print(a(4))
print(a(4))
print(a(4))
print(a(3))
print(a(4))
输出:
arg is : 4
16
16
16
arg is : 4
16
arg is : 3
9
16
我不明白你的缓存规则。函数是否多次返回一件事?如果这个url没有参数,你怎么知道潜在的返回值是本地缓存的? – tdelaney
我问过这个问题,因为听起来你根本就不想要lru缓存。这听起来像你想在一段时间内使用url返回值,然后刷新它。你能以某种方式确认吗? – tdelaney
@tdelaney所以我从URL中获取的资源偶尔会更新(如每几个小时一次)。我希望函数缓存函数的返回值,并且在网页更新的情况下每更新一次缓存设置几个小时。 – EndenDragon