[Python-ideas] caching properties

Jared Grubb jared.grubb at gmail.com
Thu Apr 30 01:09:31 CEST 2009


On 29 Apr 2009, at 15:33, Benjamin Peterson wrote:
> I think it would be nice to add a "cache" argument to the property()
> constructor. When "cache" was True, property would only ask the  
> getter function
> once for the result. This would simplify properties that require  
> expensive
> operations to compute.

You know, I have been wishing for something like this as well. I  
contribute from time to time to the SCons project (a Python-based  
build system), and caching values of things is crucial to its  
performance.

I had hoped to use a pattern like this (which doesnt work):

class Foo(object):
    def _get_path(self):
         # Compute it
         path = do_something_to_compute_path()
         # Replace the property with the value itself, all future  
lookups get this value immediately
         object.__setattr__(self, 'path', path)  # (note: this is  
illegal and doesnt actually work)
         return path
    path = property(_get_path)

    def bar(self):
         # For whatever reason, this operation invalidated the cached  
value, so we reset it.
         # If and only if queried again is the new value created
         object.__setattr__(self, 'path', property(_get_path))

This would replace the way that SCons currently does it (doing this  
from memory, but the gist is right):

      def _old_way_get_path(self):
           try:
               cache = self._cache
               return cache['path']
           except KeyError:
               path = cache['path'] = do_something_to_compute_path()
               return path
      def old_bar(self):
            # invalidate the value:
            del self._cache['path']

The old way works, but every cached call "obj.path" requires three  
dict lookups (someobj.path, self._cache, and cache['path']), whereas  
the first pattern requires exactly one dict lookup for the cached  
value (someobj.path).

I would definitely like to see some mechanism (not necessarily how I  
imagined it) for supporting cached value lookups efficiently. I am  
curious to see how this discussion goes.

Jared



More information about the Python-ideas mailing list