title: Caching data within a Python class (to avoid expensive filesystem reads on App Engine)
body: <p>This question isn't entirely App Engine specific, but it might help knowing the context: I have a kind of "static site generator" on App Engine that renders pages and allows them to be styled via various themes and theme settings. The themes are currently stored directly on the App Engine filesystem and uploaded with the application. A theme consists of a few templates and yaml configuration data.</p>
  
  <p>To encapsulate working with themes, I have a <code>Theme</code> class. <code>theme = Theme('sunshine')</code>, for example, constructs a Theme instance that loads and parses the configuration data of the theme called 'sunshine', and allows calls like <code>theme.render_template('index.html')</code> that automatically load and render the correct file on the filesystem.</p>
  
  <p>Problem is, loading and especially parsing a Theme's (yaml) configuration data every time a new request comes in and instantiates a <code>Theme</code> is expensive. So, I want to cache the data within the processes/App Engine instances and maybe later within memcached.</p>
  
  <p>Until now, I've used very simple caches like so:</p>
  
  <pre><code>class Theme(object):
       _theme_variables_cache = {}
  
       def __init__(self, name):
           self.name = name
  
           if name not in Theme._theme_variables_cache:
               Theme._theme_variables[name] = self.load_theme_variables()
  
  ...
  </code></pre>
  
  <p><em>(I'm aware that the config could be read multiple times when several requests hit the constructor at the same time. I don't think it causes problems though.)</em></p>
  
  <p>But that kind of caching gets ugly really quickly. I have several different things I want to read from config files and all of the caches are dictionaries because every different theme 'name' also points to a different underlying configuration.</p>
  
  <p>The last idea I had was creating a function like <code>Theme._cached_func(func)</code> that will only execute func when the functions result isn't already cached for the specific template (remember, when the object represents a different template, the cached value can also be different). So I could use it like: <code>self.theme_variables = Theme._cached_func(self.load_theme_variables())</code>, but, I have a feeling I'm missing something obvious here as I'm still pretty new to Python.</p>
  
  <p>Is there an obvious and clean Python caching pattern that will work for such a situation without cluttering up the entire class with cache logic? I think I can't just memoize function results via decorators or something because different templates will have to have different caches. I don't even need any "stale" cache handling because the underlying configuration data doesn't change while a process runs.</p>
  
  <p><strong>Update</strong></p>
  
  <p>I ended up doing it like that:</p>
  
  <pre><code>class ThemeConfig(object):
      __instances_cache = {}
  
      @classmethod
      def get_for(cls, theme_name):
          return cls.__instances_cache.setdefault(
              theme_name, ThemeConfig(theme_name))
  
      def __init__(self, theme_name):
          self.theme_name = theme_name
          self._load_assets_urls()  # those calls load yaml files
          self._load_variables()
  ...
  
  
  class Theme(object):
      def __init__(self, theme_name):
          self.theme_name = theme_name
          self.config = ThemeConfig.get_for(theme_name)
  ...
  </code></pre>
  
  <p>So <code>ThemeConfig</code> stores all the configuration stuff that's read from the filesystem for a theme and the factory method <code>ThemeConfig.get_for</code> will always hand out the same ThemeConfig instance for the same theme name. The only caching logic I have is the one line in the factory method, and <code>Theme</code> objects are still as temporary and non-shared as they always were, so I can use and abuse them however I wish.</p>