Is this pythonic?

Peter Otten __peter__ at web.de
Wed Nov 23 06:21:14 EST 2016


Frank Millman wrote:

> Hi all
> 
> Sometimes I write something that I think is quite clever, but later on I
> look at it and ask 'What was I thinking?'.
> 
> I have just come up with a 'clever' solution to a problem. Would this
> cause raised eyebrows if you were reviewing this?
> 
> I have a class that represents a single database column - there could be
> hundreds of instances at any time.
> 
> 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.
> 
> In many cases the computed value is never actually requested, so I want to
> delay the computation until the first call to getval().
> 
> I could add an 'if computation_required: ' block to getval(), but I am
> trying to avoid that, partly because this would have to be checked for
> every call to getval() but would only used in a small number of cases, and
> partly because I have a few subclasses where getval() is over-ridden so I
> would have to add the extra code to every one (or call the superclass on
> every one).
> 
> 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

You can also have the method replace itself:

>>> class Foo:
...     def get_val(self):
...         print("computing...")
...         val = self._val = 42
...         self.get_val = self.get_cached_val
...         return val
...     def get_cached_val(self):
...         return self._val
... 
>>> foo = Foo()
>>> foo.get_val()
computing...
42
>>> foo.get_val()
42

 
> 4. In _getval_with_comp, perform the computation, then add the following -
>         self.getval = self._getval
>         return self._getval()
> 
> What is the verdict? -1, 0, or +1?
> 
> Frank Millman





More information about the Python-list mailing list