Is this pythonic?

Steve D'Aprano steve+python at pearwood.info
Wed Nov 23 06:15:15 EST 2016


On Wed, 23 Nov 2016 08:10 pm, Frank Millman wrote:

[...]
> The class has a getval() method to return the current value.
> 
> Usually the value is stored in the instance, and can be returned
> immediately, but sometimes it has to be computed, incurring further
> database lookups.

This is called memoisation, or caching, and is a perfectly standard
programming technique. It's not without its traps though: there's a famous
quote that says there are only two hard problems in computing, naming
things and cache invalidation. But putting that aside:


def getval(self):
    sentinel = object()
    value = getattr(self, '_cached_value', sentinel)
    if value is sentinel:
        # compute the value and store it
        value = ...
        self._cached_value = value
    return value

To invalidate the cache and force a recalculation:

    del self._cached_value


Now it's easy to override:

class Subclass(ParentClass):
    def getval(self):
        value = super(Subclass, self).getval()
        return value + 1



> This is what I have come up with.
> 
> 1. Rename all instances of 'getval()' to '_getval()'.
> 
> 2. Add a new method '_getval_with_comp()'.
> 
> 3. When instantiating an object, check if it would need computation -
>     if computation_required:
>         self.getval = self._getval_with_comp
>     else:
>         self.getval = self._getval

So this check only happens once, on instantiation? And you're sure that once
the instance is created, there will never be any circumstances where you
want to re-calculate the value?



> 4. In _getval_with_comp, perform the computation, then add the following -
>         self.getval = self._getval
>         return self._getval()

So you have something like this?

def _getval(self):
    return self._cached_value

def __getval_with_comp(self):
    value = ... # long computation
    self._cached_value = value
    self.getval = self._getval
    # return value
    return self._getval()
    # why call the method when you already know the answer?

    
How are subclasses supposed to override getval?




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list