Description
How to use the Python decorator pattern to cache the result values of your computationally expensive method calls.
Cache decorators are convenient methods caching of function return values.
They work like this:
@cache_this_function
def my_slow_function():
# This is run only once and all subsequent calls get value from the cache
return
Warning
Cache decorators do not work with methods or functions using generators (yield). The cache stores empty value.
The plone.memoize package offers helpful function decorators to cache return values.
See also using memcached backend for memoizers.
Example:
from plone.memoize import forever
@forever.memoize
def getFields(area, subject):
""" Get all fields inside area / subject.
Results is cached for process lifetime.
@return: List of internal fields
"""
schema = getSchema(area)
return [field for field in schema if field["subject"] == subject]
This pattern shows how to avoid recalculating the same value repeatedly during the lifecycle of an HTTP request object.
This is useful if the same view/utility is going to be called many times from different places for the same HTTP request.
The plone.memoize.view package provides necessary decorators for BrowserView based classes.
from plone.memoize.view import memoize, memoize_contextless
class MyView(BrowserView):
@memoize
def getValue():
""" This value is recalculated for every new BrowserView context
per request
"""
return "something"
@memoize_contextless
def getValueNoContext():
""" This value is recalculated for all context objects once per
request
"""
return "something"
If you have a custom Archetypes accessor method, you can avoid recalculating it during the request processing.
Example:
def getParsedORADataCached(self):
""" Same as above, but does not run through JSON reader every time.
"""
# Manually store the result on HTTP request
# object annotations
# Use function name + Archetypes unique identified as the key
key = "parsed-ora-data-" + self.UID()
cache = IAnnotations(self.REQUEST)
data = cache.get(key, None)
if not data:
data = self.getParsedORAData()
cache[key] = data
return data
The source code of this file is hosted on GitHub. Everyone can update and fix errors in this document with few clicks - no downloads needed.
For basic information about updating this manual and Sphinx format please see Writing and updating the manual guide.