One-Shot Property?

Leif K-Brooks eurleif at
Tue Jan 18 13:35:33 EST 2005

Kevin Smith wrote:
> I have many cases in my code where I use a property for calculating a 
> value on-demand.  Quite a few of these only need to be called once.  
> After that the value is always the same.  In these properties, I set a 
> variable in the instance as a cached value and return that value on 
> subsequent calls.  It would be nice if there was a descriptor that would 
> do this automatically.  Actually, what would be really nice is if I 
> could replace the property altogether and put the calculated value in 
> its place after the first call, but the property itself prevents me from 
> doing that.

This should do it:

class CachingProperty(object):
     def __init__(self, attr_name, calculate_function):
         self._name = attr_name
         self._calculate = calculate_function

     def __get__(self, obj, type=None):
         if obj is None:
             return self
             value = self._calculate(obj)
         setattr(obj, self._name, value)
         return value

And example code:

 >>> class Foo(object):
...     def calculate_value(self):
...         print 'Calculating...'
...         return 42
...     foo = CachingProperty('foo', calculate_value)
 >>> bar = Foo()
 >>> bar.__dict__
 >>> # Notice that the print statement doesn't run this time
 >>> bar.__dict__
{'foo': 42}

More information about the Python-list mailing list