使用
flask-caching
时
memoize
的默认行为是如果指定的超时已到则执行该函数,然后返回并保存新结果。但是,现在过时的(之前缓存的)结果不会被删除。这对于大多数应用程序来说没问题,但如果缓存结果很大,就会出现问题。
flask-caching
暴露
CACHE_THRESHOLD
(
https://flask-caching.readthedocs.io/en/latest/
)来控制通过指定总共保留多少个文件来实现此行为。将其设置为 1 应该在缓存中只保留 1 个项目,因此只有最近执行的函数才被允许保留副本。
有什么方法可以控制每个函数吗?理想情况下,我有一些函数,我不关心项目是否被保留(因为大小不是问题),但其他函数的返回值太大,我想在函数执行后立即删除旧的缓存值超时后再次超时。
我知道有一种方法
delete_memoized
可以在函数的基础上执行此操作,但如果我使用它来手动清除缓存,我需要知道它是否已过期,并且我'我不确定是否有办法做到这一点(除了这个逻辑已经在
flask-caching
端实现,所以我真的不认为有必要为这样的事情重新发明轮子)。
不幸的是,
flask-caching
没有内置的方法来为每个函数指定缓存阈值。
CACHE_THRESHOLD
选项是一个全局设置,适用于所有使用
flask-caching
缓存的内容。
但是,可以通过结合使用
delete_memoized
装饰器和缓存键来实现所需的行为。这个想法是在调用缓存函数之前删除该函数的旧缓存条目。以下是如何操作:
from flask import Flask
from flask_caching import Cache
app = Flask(__name__)
cache = Cache(app, config={'CACHE_TYPE': 'simple'})
def generate_cache_key(function, *args, **kwargs):
# 为给定函数及其参数生成唯一缓存键
key = function.__name__ + str(args) + str(kwargs)
return key
def memoized_with_threshold(timeout=None, unless=None):
def decorator(f):
@cache.memoize(timeout=timeout, unless=unless)
def decorated_function(*args, **kwargs):
# 在调用缓存函数之前删除旧缓存条目
cache.delete_memoized(f, *args, **kwargs)
return f(*args, **kwargs)
return decorated_function
return decorator
@app.route('/large_data')
@memoized_with_threshold(timeout=60)
def large_data():
# ... 生成和返回大型数据集 ...
return large_dataset
@app.route('/small_data')
@cache.memoize(timeout=60)
def small_data():
# ... 生成和返回小型数据集 ...
return small_dataset
在这个例子中:
-
memoized_with_threshold
是一个自定义装饰器,它封装了cache.memoize
。 -
在
decorated_function
内部,我们首先使用cache.delete_memoized(f, *args, **kwargs)
删除与当前参数对应的函数f
的任何现有缓存条目。 - 然后,我们像往常一样调用并返回缓存函数。
使用此设置,
large_data
函数将在每次执行后有效地清除其缓存,而
small_data
函数将使用默认的缓存行为。
这种方法避免了重新实现缓存逻辑,因为它利用了
flask-caching
提供的现有功能。但是,需要注意的是,使用
delete_memoized
可能会稍微增加开销,因为它会在每次函数调用之前使缓存无效。