@lru_cache on functions with no arguments

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Aug 2 05:00:56 EDT 2017


On Tue, 01 Aug 2017 11:05:38 -0400, Terry Reedy wrote:

> On 8/1/2017 7:06 AM, Matt Wheeler wrote:
>> On Tue, 1 Aug 2017 at 02:32 Terry Reedy <tjreedy at udel.edu> wrote:
>> 
>>> On 7/31/2017 7:31 PM, tom at tomforb.es wrote:
>>>> As part of the Python 3 cleanup in Django there are a fair few uses
>>>> of
>>> @functools.lru_cache on functions that take no arguments.
>>>
>>> This makes no sense to me.  If the function is being called for
>>> side-effects, then it should not be cached.  If the function is being
>>> called for a result, different for each call, calculated from a
>>> changing environment, then it should not be cached.  (Input from disk
>>> is an example.) If the function returns a random number, or a
>>> non-constant value from an oracle (such as a person), it should not be
>>> cached.  If the function returns a constant (possible calculated
>>> once), then the constant should just be bound to a name (which is a
>>> form of caching) rather than using the overkill of an lru cache.  What
>>> possibility am I missing?
>>>
>>>
>> A function which is moderately expensive to run, that will always
>> return the same result if run again in the same process, and which will
>> not be needed in every session.
> 
> In initialization section:
> answer = None
> 
> Somewhere else:
> answer = expensive_calculaton() if answer is None else answer
> 
> The conditional has to be cheaper than accessing lru cache.  There can
> be more than one of these.


One conditional has to be cheaper than accessing lru cache.

Debugging the errors from forgetting to wrap every single reference to 
"answer" in a "if answer is None" test is not so cheap.

Maintaining twice as much state (one function plus one global variable, 
instead of just one function) is not so cheap.

Sometimes paying a small cost to avoid having to occasionally pay a large 
cost is worth it.

This is effectively the "Only Once" decorator pattern, which guarantees a 
function only executes once no matter how often you call it.






-- 
“You are deluded if you think software engineers who can't write 
operating systems or applications without security holes, can write 
virtualization layers without security holes.” —Theo de Raadt



More information about the Python-list mailing list