ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# Flask-Cache ## 安装 使用下面的命令行安装 Flask-Cache: ``` $ easy_install Flask-Cache ``` 或者可以用下面的命令行,如果安装了 pip: ``` $ pip install Flask-Cache ``` ## 使用 缓存(Cache)是通过使用一个 `Cache` 实例进行管理: ``` from flask import Flask from flask.ext.cache import Cache app = Flask(__name__) # Check Configuring Flask-Cache section for more details cache = Cache(app,config={'CACHE_TYPE': 'simple'}) ``` 你能够用 **init_app** 方法在初始化 `Cache` 后设置它: ``` cache = Cache(config={'CACHE_TYPE': 'simple'}) app = Flask(__name__) cache.init_app(app) ``` 如果有多个 `Cache` 实例以及每一个实例都有不同后端的话(换句话说,就是每一个实例使用不用的缓存类型CACHE_TYPE),使用配置字典是十分有用的: ``` #: Method A: During instantiation of class cache = Cache(config={'CACHE_TYPE': 'simple'}) #: Method B: During init_app call cache.init_app(app, config={'CACHE_TYPE': 'simple'}) ``` New in version 0.7. ## 缓存视图函数 使用装饰器 [`cached()`](#flask.ext.cache.Cache.cached "flask.ext.cache.Cache.cached") 能够缓存视图函数。它在默认情况下使用请求路径(request.path)作为cache_key: ``` @cache.cached(timeout=50) def index(): return render_template('index.html') ``` 该装饰器有一个可选的参数:`unless`,它允许一个可调用的、返回值是True或者False的函数。如果 `unless` 返回 `True`,将会完全忽略缓存机制(内置的缓存机制会完全不起作用)。 ## 缓存其它函数 同样地,使用 `@cached` 装饰器也能够缓存其它非视图函数的结果。唯一的要求是需要指定 `key_prefix`,否则会使用请求路径(request.path)作为cache_key: ``` @cache.cached(timeout=50, key_prefix='all_comments') def get_all_comments(): comments = do_serious_dbio() return [x.author for x in comments] cached_comments = get_all_comments() ``` ## Memoization(一种缓存技术) 请参看 [`memoize()`](#flask.ext.cache.Cache.memoize "flask.ext.cache.Cache.memoize") 在memoization中,函数参数同样包含cache_key。 Note 如果函数不接受参数的话,[`cached()`](#flask.ext.cache.Cache.cached "flask.ext.cache.Cache.cached") 和 [`memoize()`](#flask.ext.cache.Cache.memoize "flask.ext.cache.Cache.memoize") 两者的作用是一样的。 Memoize同样也为类成员函数而设计,因为它根据 [identity](http://docs.python.org/library/functions.html#id) 将 ‘self’ 或者 ‘cls’ 参数考虑进作为缓存键的一部分。 memoization背后的理论是:在一次请求中如果一个函数需要被调用多次,它只会计算第一次使用这些参数调用该函数。例如,存在一个决定用户角色的 sqlalchemy对象,在一个请求中可能需要多次调用这个函数。为了避免每次都从数据库获取信息,你可以这样做: ``` class Person(db.Model): @cache.memoize(50) def has_membership(self, role_id): return Group.query.filter_by(user=self, role_id=role_id).count() >= 1 ``` Warning 使用可变对象(例如类)作为缓存键的一部分是十分棘手的。建议最好不要让一个对象的实例成为一个memoized函数。然而,memoize在处理参数的时候会执行repr(),因此如果一个对象有`__repr__`函数,并且返回一个唯一标识该对象的字符串,它将能够作为缓存键的一部分。 例如,一个sqlalchemy person对象,它返回数据库的ID作为唯一标识符的一部分: ``` class Person(db.Model): def __repr__(self): return "%s(%s)" % (self.__class__.__name__, self.id) ``` ### 删除memoize的缓存 New in version 0.2. 在每个函数的基础上,您可能需要删除缓存。使用上面的例子,让我们来改变用户权限,并将它们分配到一个角色,如果它们新拥有或者失去某些成员关系,现在你需要重新计算。你能够用 [`delete_memoized()`](#flask.ext.cache.Cache.delete_memoized "flask.ext.cache.Cache.delete_memoized") 函数来达到目的: ``` cache.delete_memoized('user_has_membership') ``` Note 如果仅仅只有函数名作为参数,所有的memoized的版本将会无效的。然而,您可以删除特定的缓存提供缓存时相同的参数值。在下面的例子中,只有 `user` 角色缓存被删除: ``` user_has_membership('demo', 'admin') user_has_membership('demo', 'user') cache.delete_memoized('user_has_membership', 'demo', 'user') ``` ## 缓存Jinja2片段 用法: ``` {% cache [timeout [,[key1, [key2, ...]]]] %} ... {% endcache %} ``` 默认情况下“模版文件路径”+“片段开始的函数”用来作为缓存键。同样键名是可以手动设置的。键名串联成一个字符串,这样能够用于避免同样的块在不同模版被重复计算。 设置 timeout 为 None,并且使用了自定义的键: ``` {% cache None "key" %}... ``` 为了删除缓存值,为“del”设置超时时间: ``` {% cache 'del' %}... ``` 如果提供键名,你可以很容易地产生模版的片段密钥,从模板上下文外删除它: ``` from flask.ext.cache import make_template_fragment_key key = make_template_fragment_key("key1", vary_on=["key2", "key3"]) cache.delete(key) ``` 例子: ``` Considering we have render_form_field and render_submit macroses. {% cache 60*5 %} <form> {% render_form_field form.username %} {% render_submit %} </form> {% endcache %} ``` ## 清除缓存 请参看 [`clear()`](#flask.ext.cache.Cache.clear "flask.ext.cache.Cache.clear"). 下面的例子是一个用来清空应用缓存的脚本: ``` from flask.ext.cache import Cache from yourapp import app, your_cache_config cache = Cache() def main(): cache.init_app(app, config=your_cache_config) with app.app_context(): cache.clear() if __name__ == '__main__': main() ``` Warning 某些缓存类型不支持完全清空缓存。同样,如果你不使用键前缀,一些缓存类型将刷新整个数据库。请确保你没有任何其他数据存储在缓存数据库中。 ## 配置Flask-Cache Flask-Cache有下面一些配置项: `CACHE_TYPE` 指定哪些类型的缓存对象来使用。 这是一个输入字符串,将被导入并实例化。 它假设被导入的对象是一个依赖于werkzeug缓存API, 返回缓存对象的函数。 对于werkzeug.contrib.cache对象,不必给出完整的字符串, 只要是下列这些名称之一。 内建缓存类型: * **null**: NullCache (default) * **simple**: SimpleCache * **memcached**: MemcachedCache (pylibmc or memcache required) * **gaememcached**: GAEMemcachedCache * **redis**: RedisCache (Werkzeug 0.7 required) * **filesystem**: FileSystemCache * **saslmemcached**: SASLMemcachedCache (pylibmc required) | | | | --- | --- | | `CACHE_NO_NULL_WARNING` | 当使用的缓存类型是’null’,不会抛出警告信息。 | | `CACHE_ARGS` | 可选的列表,在缓存类实例化的时候会对该列表进行拆分以及传递(传参)。 | | `CACHE_OPTIONS` | 可选的字典,在缓存类实例化的时候会传递该字典(传参)。 | | `CACHE_DEFAULT_TIMEOUT` | 如果没有设置延迟时间,默认的延时时间会被使用。单位为秒。 | | `CACHE_THRESHOLD` | 最大的缓存条目数,超过该数会删除一些缓存条目。仅仅用于SimpleCache和 FileSystemCache。 | | `CACHE_KEY_PREFIX` | 所有键之前添加的前缀。 这使得它可以为不同的应用程序使用相同的memcached服务器。 仅仅用于RedisCache,MemcachedCache以及GAEMemcachedCache。 | | `CACHE_MEMCACHED_SERVERS` | 服务器地址列表或元组。仅用于MemcachedCache。 | | `CACHE_MEMCACHED_USERNAME` | SASL与memcached服务器认证的用户名。 仅用于SASLMemcachedCache。 | | `CACHE_MEMCACHED_PASSWORD` | SASL与memcached服务器认证的密码。 仅用于SASLMemcachedCache。 | | `CACHE_REDIS_HOST` | Redis服务器的主机。仅用于RedisCache。 | | `CACHE_REDIS_PORT` | Redis服务器的端口。默认是6379。仅用于RedisCache。 | | `CACHE_REDIS_PASSWORD` | 用于Redis服务器的密码。仅用于RedisCache。 | | `CACHE_REDIS_DB` | Redis的db库 (基于零号索引)。默认是0。仅用于RedisCache。 | | `CACHE_DIR` | 存储缓存的目录。仅用于FileSystemCache。 | | `CACHE_REDIS_URL` | 连接到Redis服务器的URL。 例如:`redis://user:password@localhost:6379/2`。 仅用于RedisCache。 | 此外,如果标准的Flask配置项 `TESTING` 使用并且设置为True的话, **Flask-Cache** 将只会使用NullCache作为缓存类型。 ## 内建的缓存类型 ### NullCache – null 不缓存内容 * CACHE_ARGS * CACHE_OPTIONS ### SimpleCache – simple 使用本地Python字典缓存。这不是真正的线程安全。 相关配置 * CACHE_DEFAULT_TIMEOUT * CACHE_THRESHOLD * CACHE_ARGS * CACHE_OPTIONS ### FileSystemCache – filesystem 使用文件系统来存储缓存值 * CACHE_DEFAULT_TIMEOUT * CACHE_DIR * CACHE_THRESHOLD * CACHE_ARGS * CACHE_OPTIONS ### MemcachedCache – memcached 使用memcached服务器作为后端。支持pylibmc或memcache或谷歌应用程序引擎的memcache库。 相关配置项 * CACHE_DEFAULT_TIMEOUT * CACHE_KEY_PREFIX * CACHE_MEMCACHED_SERVERS * CACHE_ARGS * CACHE_OPTIONS ### GAEMemcachedCache – gaememcached MemcachedCache一个不同的名称 ### SASLMemcachedCache – saslmemcached 使用memcached服务器作为后端。使用SASL建立与memcached服务器的连接。pylibmc是必须的,libmemcached必须支持SASL。 相关配置项 * CACHE_DEFAULT_TIMEOUT * CACHE_KEY_PREFIX * CACHE_MEMCACHED_SERVERS * CACHE_MEMCACHED_USERNAME * CACHE_MEMCACHED_PASSWORD * CACHE_ARGS * CACHE_OPTIONS New in version 0.10. ### SpreadSASLMemcachedCache – spreadsaslmemcachedcache 与SASLMemcachedCache一样,但是如果大于memcached的传输安全性,默认是1M,能够跨不同的键名缓存值。使用pickle模块。 New in version 0.11. ### RedisCache – redis * CACHE_DEFAULT_TIMEOUT * CACHE_KEY_PREFIX * CACHE_REDIS_HOST * CACHE_REDIS_PORT * CACHE_REDIS_PASSWORD * CACHE_REDIS_DB * CACHE_ARGS * CACHE_OPTIONS * CACHE_REDIS_URL ## 定制缓存后端(后台) 你能够轻易地定制缓存后端,只需要导入一个能够实例化以及返回缓存对象的函数。`CACHE_TYPE` 将是你自定义的函数名的字符串。 这个函数期望得到三个参数。 * `app` * `args` * `kwargs` 你自定义的缓存对象必须是 `werkzeug.contrib.cache.BaseCache` 的子类。确保 `threshold` 是包含在kwargs参数中,因为它是所有BaseCache类通用的。 Redis的缓存实现的一个例子: ``` #: the_app/custom.py class RedisCache(BaseCache): def __init__(self, servers, default_timeout=500): pass def redis(app, config, args, kwargs): args.append(app.config['REDIS_SERVERS']) return RedisCache(*args, **kwargs) ``` 在这个例子中,`CACHE_TYPE` 可能就是 `the_app.custom.redis`。 PylibMC缓存实现的一个例子: ``` #: the_app/custom.py def pylibmccache(app, config, args, kwargs): return pylibmc.Client(servers=config['CACHE_MEMCACHED_SERVERS'], username=config['CACHE_MEMCACHED_USERNAME'], password=config['CACHE_MEMCACHED_PASSWORD'], binary=True) ``` 在这个例子中,`CACHE_TYPE` 可能就是 `the_app.custom.pylibmccache`。 ## API `class flask.ext.cache.Cache(app=None, with_jinja2_ext=True, config=None)` This class is used to control the cache objects. `add(*args, **kwargs)` Proxy function for internal cache object. `cached(timeout=None, key_prefix='view/%s', unless=None)` Decorator. Use this to cache a function. By default the cache key is `view/request.path`. You are able to use this decorator with any function by changing the `key_prefix`. If the token `%s` is located within the `key_prefix` then it will replace that with `request.path` Example: ``` # An example view function @cache.cached(timeout=50) def big_foo(): return big_bar_calc() # An example misc function to cache. @cache.cached(key_prefix='MyCachedList') def get_list(): return [random.randrange(0, 1) for i in range(50000)] my_list = get_list() ``` Note You MUST have a request context to actually called any functions that are cached. New in version 0.4: The returned decorated function now has three function attributes assigned to it. These attributes are readable/writable. **uncached** The original undecorated function **cache_timeout** The cache timeout value for this function. For a custom value to take affect, this must be set before the function is called. **make_cache_key** A function used in generating the cache_key used. Parameters: * **timeout** – Default None. If set to an integer, will cache for that amount of time. Unit of time is in seconds. * **key_prefix** – Default ‘view/%(request.path)s’. Beginning key to . use for the cache key. New in version 0.3.4: Can optionally be a callable which takes no arguments but returns a string that will be used as the cache_key. * **unless** – Default None. Cache will _always_ execute the caching facilities unless this callable is true. This will bypass the caching entirely. `clear()` Proxy function for internal cache object. `delete(*args, **kwargs)` Proxy function for internal cache object. `delete_many(*args, **kwargs)` Proxy function for internal cache object. `delete_memoized(f, *args, **kwargs)` Deletes the specified functions caches, based by given parameters. If parameters are given, only the functions that were memoized with them will be erased. Otherwise all versions of the caches will be forgotten. Example: ``` @cache.memoize(50) def random_func(): return random.randrange(1, 50) @cache.memoize() def param_func(a, b): return a+b+random.randrange(1, 50) ``` ``` >>> random_func() 43 >>> random_func() 43 >>> cache.delete_memoized('random_func') >>> random_func() 16 >>> param_func(1, 2) 32 >>> param_func(1, 2) 32 >>> param_func(2, 2) 47 >>> cache.delete_memoized('param_func', 1, 2) >>> param_func(1, 2) 13 >>> param_func(2, 2) 47 ``` Delete memoized is also smart about instance methods vs class methods. When passing a instancemethod, it will only clear the cache related to that instance of that object. (object uniqueness can be overridden > When passing a classmethod, it will clear all caches related across all instances of that class. Example: ``` class Adder(object): @cache.memoize() def add(self, b): return b + random.random() ``` ``` >>> adder1 = Adder() >>> adder2 = Adder() >>> adder1.add(3) 3.23214234 >>> adder2.add(3) 3.60898509 >>> cache.delete_memoized(adder.add) >>> adder1.add(3) 3.01348673 >>> adder2.add(3) 3.60898509 >>> cache.delete_memoized(Adder.add) >>> adder1.add(3) 3.53235667 >>> adder2.add(3) 3.72341788 ``` Parameters: * **fname** – Name of the memoized function, or a reference to the function. * **\*args** – A list of positional parameters used with memoized function. * **\*\*kwargs** – A dict of named parameters used with memoized function. Note Flask-Cache uses inspect to order kwargs into positional args when the function is memoized. If you pass a function reference into `fname` instead of the function name, Flask-Cache will be able to place the args/kwargs in the proper order, and delete the positional cache. However, if `delete_memoized` is just called with the name of the function, be sure to pass in potential arguments in the same order as defined in your function as args only, otherwise Flask-Cache will not be able to compute the same cache key. Note Flask-Cache maintains an internal random version hash for the function. Using delete_memoized will only swap out the version hash, causing the memoize function to recompute results and put them into another key. This leaves any computed caches for this memoized function within the caching backend. It is recommended to use a very high timeout with memoize if using this function, so that when the version has is swapped, the old cached results would eventually be reclaimed by the caching backend. `delete_memoized_verhash(f, *args)` Delete the version hash associated with the function. ..warning: ``` Performing this operation could leave keys behind that have been created with this version hash. It is up to the application to make sure that all keys that may have been created with this version hash at least have timeouts so they will not sit orphaned in the cache backend. ``` `get(*args, **kwargs)` Proxy function for internal cache object. `get_many(*args, **kwargs)` Proxy function for internal cache object. `init_app(app, config=None)` This is used to initialize cache with your app object `memoize(timeout=None, make_name=None, unless=None)` Use this to cache the result of a function, taking its arguments into account in the cache key. Information on [Memoization](http://en.wikipedia.org/wiki/Memoization). Example: ``` @cache.memoize(timeout=50) def big_foo(a, b): return a + b + random.randrange(0, 1000) ``` ``` >>> big_foo(5, 2) 753 >>> big_foo(5, 3) 234 >>> big_foo(5, 2) 753 ``` New in version 0.4: The returned decorated function now has three function attributes assigned to it. **uncached** The original undecorated function. readable only **cache_timeout** The cache timeout value for this function. For a custom value to take affect, this must be set before the function is called. readable and writable **make_cache_key** A function used in generating the cache_key used. readable and writable Parameters: * **timeout** – Default None. If set to an integer, will cache for that amount of time. Unit of time is in seconds. * **make_name** – Default None. If set this is a function that accepts a single argument, the function name, and returns a new string to be used as the function name. If not set then the function name is used. * **unless** – Default None. Cache will _always_ execute the caching facilities unelss this callable is true. This will bypass the caching entirely. New in version 0.5: params `make_name`, `unless` `set(*args, **kwargs)` Proxy function for internal cache object. `set_many(*args, **kwargs)` Proxy function for internal cache object. ## Changelog ### Version 0.13 2014-04-21 * Port to Python >= 3.3 (requiring Python 2.6/2.7 for 2.x). * Fixed bug with using per-memoize timeouts greater than the default timeout * Added better support for per-instance memoization. * Various bug fixes ### Version 0.12 2013-04-29 * Changes jinja2 cache templates to use stable predictable keys. Previously the key for a cache tag included the line number of the template, which made it difficult to predict what the key would be outside of the application. * Adds config variable `CACHE_NO_NULL_WARNING` to silence warning messages when using ‘null’ cache as part of testing. * Adds passthrough to clear entire cache backend. ### Version 0.11.1 2013-04-7 * Bugfix for using memoize on instance methods. The previous key was id(self), the new key is repr(self) ### Version 0.11 2013-03-23 * Fail gracefully in production if cache backend raises an exception. * Support for redis DB number * Jinja2 templatetag cache now concats all args together into a single key instead of treating each arg as a separate key name. * Added delete memcache version hash function * Support for multiple cache objects on a single app again. * Added SpreadSASLMemcached, if a value is greater than the memcached threshold which defaults to 1MB, this splits the value across multiple keys. * Added support to use URL to connect to redis. ### Version 0.10.1 2013-01-13 * Added warning message when using cache type of ‘null’ * Changed imports to relative instead of absolute for AppEngine compatibility ### Version 0.10.0 2013-01-05 * Added `saslmemcached` backend to support Memcached behind SASL authentication. * Fixes a bug with memoize when the number of args != number of kwargs ### Version 0.9.2 2012-11-18 * Bugfix with default kwargs ### Version 0.9.1 2012-11-16 * Fixes broken memoized on functions that use default kwargs ### Version 0.9.0 2012-10-14 * Fixes memoization to work on methods. ### Version 0.8.0 2012-09-30 * Migrated to the new flask extension naming convention of flask_cache instead of flaskext.cache * Removed unnecessary dependencies in setup.py file. * Documentation updates ### Version 0.7.0 2012-08-25 * Allows multiple cache objects to be instantiated with different configuration values. ### Version 0.6.0 2012-08-12 * Memoization is now safer for multiple applications using the same backing store. * Removed the explicit set of NullCache if the Flask app is set testing=True * Swapped Conditional order for key_prefix ### Version 0.5.0 2012-02-03 * Deleting memoized functions now properly functions in production environments where multiple instances of the application are running. * get_memoized_names and get_memoized_keys have been removed. * Added `make_name` to memoize, make_name is an optional callable that can be passed to memoize to modify the cache_key that gets generated. * Added `unless` to memoize, this is the same as the unless parameter in `cached` * memoization now converts all kwargs to positional arguments, this is so that when a function is called multiple ways, it would evaluate to the same cache_key ### Version 0.4.0 2011-12-11 * Added attributes for uncached, make_cache_key, cache_timeout to the decorated functions. ### Version 0.3.4 2011-09-10 * UTF-8 encoding of cache key * key_prefix argument of the cached decorator now supports callables. ### Version 0.3.3 2011-06-03 Uses base64 for memoize caching. This fixes rare issues where the cache_key was either a tuple or larger than the caching backend would be able to support. Adds support for deleting memoized caches optionally based on function parameters. Python 2.5 compatibility, plus bugfix with string.format. Added the ability to retrieve memoized function names or cache keys. ### Version 0.3.2 Bugfix release. Fixes a bug that would cause an exception if no `CACHE_TYPE` was supplied. ### Version 0.3.1 Pypi egg fix. ### Version 0.3 * CACHE_TYPE changed. Now one of [‘null’, ‘simple’, ‘memcached’, ‘gaememcached’, ‘filesystem’], or an import string to a function that will instantiate a cache object. This allows Flask-Cache to be much more extensible and configurable. ### Version 0.2 * CACHE_TYPE now uses an import_string. * Added CACHE_OPTIONS and CACHE_ARGS configuration values. * Added delete_memoized ### Version 0.1 * Initial public release