Cache decorators

Description

How to use the Python decorator pattern to cache the result values of your computationally expensive method calls.

Introduction

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.

Cache result for process lifecycle

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]

Caching per request

This pattern shows how to avoid recalculating the same value repeatedly during the lifecycle of an HTTP request object.

Caching on BrowserViews

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"

Caching on Archetypes accessors

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



Edit this document

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.

  1. Go to Cache decorators on GitHub.
  2. Press Fork and edit this file button.
  3. Edit file contents using GitHub's text editor in your web browserm
  4. Fill in the Commit message text box at the end of the page telling why you did the changes. Press Propose file change button next to it when done.
  5. On Send a pull request page you don't need to fill in text anymore. Just press Send pull request button.
  6. Your changes are now queued for review under project's Pull requests tab on Github.

For basic information about updating this manual and Sphinx format please see Writing and updating the manual guide.