乐趣区

关于python:Flaskcaching-的缓存与删除-避坑指南

根本用法

基于 Flask 利用,难免会用到 Flask-cache (或 Flask-cacheing,两者 API 基本相同)。它通过装璜器,十分优雅地实现了函数调用的缓存。装璜器能够间接加在 view function,或者一般 function 上,相似上面的样子:

@app.route('/demo/student/all', methods=['GET'])
@cache.cached(timeout=600)
def get():
    students = Student.query.all()
    return response_ok(students)

(如果函数有参数,并且心愿针对不同实参值,做不同的缓存,那就用 _@cache.memerized _装璜器)
增加了装璜器的函数,在第一次被调用之后,返回值就被在缓存有效期内,示例中的timeout 参数,保障了缓存在 600 秒后超时生效,再次调用函数本体取得最新数据。

view function 缓存管制

但有时咱们须要管制这个缓存的更新——比方下面的例子中,每次新增一个学生、或者更改学生数据,就从新刷新一下缓存,而不须要等它天然超时。这时就须要显式调用 delete 函数,例如:

del_res = cache.delete('/demo/student/all')

对于 view function 来说,这里 delete 的参数,就恰好等于 route 里的 path,如果 route 来自于一个下级的 blueprint,要记得把下级 path 带上。
如果你要指定 cache 的 key,能够加上 key_prefix 参数,相似上面这样:

@app.route('/demo/student/all', methods=['GET'])
@cache.cached(timeout=600, key_prefix='res_student_all')
def get():
    ...

留神 第一个坑 来了:因为名字里有个 prefix,你可能会感觉它是 key 的前缀,删除的时候,会想着怎么组合一下这个参数和 path;然而实际上却不必任何组合,path 在这里曾经有效了,删除时间接用这个 key_prefix 当参数就能够:

del_res = cache.delete('res_student_all')

事实上,这个 key_prefix 既不是 key 的前缀,也不是整个 key,它应该叫 key 的后缀更正当,真正保留的 key(存在那里取决于配置,能够有内存缓存 SimpleCache、redis 缓存等等)前缀是这个样子的:**flask_cache_**,而无论是 path 还是 key_prefix,都会在 hash 之后拼接在前面。

一般 function 缓存管制

简略函数

如果是一般的 function,要应用 @cache.memoize 装璜器,同样反对 timeout 参数,如下:

@cache.memoize(timeout=60)
def get_number():
    return 5

删除 memoize 要更直观一些,间接传函数就能够啦:

del_res = cache.delete_memoize(get_number)

如果该函数有参数:

@cache.memoize(timeout=60)
def get_number(x):
    return 5 + x

删除时加参数,示意只删除这个参数对应的缓存,不加参数,示意删除该函数的所有实参值对应缓存:

del_res = cache.delete_memoize(get_number, 5)    # 只删除 x = 5 的缓存
del_res = cache.delete_memoize(get_number)    # 删除所有 get_number 缓存

类函数

这时 第二个坑 来了,如果这是个类函数呢?

@cache.memoize(timeout=60)
class Calc:
    @classmethod
    def get_number(x):
        return 5 + x

删除时,只传函数名,或者函数名加参数,是删不掉的:

del_res = cache.delete_memoize(Calc.get_number, 5)    # 无奈删除 x = 5 的缓存
del_res = cache.delete_memoize(Calc.get_number)    # 无奈删除所有 get_number 缓存

官网文档说,“要把类当做第一个参数传进来”,这个的表述非常容易误会,实际上应该是参数列表里的第一个,所以要像上面这样传:

del_res = cache.delete_memoize(Calc.get_number, Calc, 5)    # 删除 x = 5 的缓存
del_res = cache.delete_memoize(Calc.get_number, Calc)    # 删除所有 get_number 缓存
退出移动版