skipping __init__ and using exploiting a class member instead

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Oct 19 18:30:13 EDT 2013


On Sat, 19 Oct 2013 14:44:55 -0700, Peter Cacioppi wrote:

> Is the following considered poor Python form?
> 
> class Foo (object) :
>     _lazy = None
>     def foo(self, x) :
>         _lazy = _lazy or self.get_something(x)
>     def get_something(self, x) :
>         # doesn't really matter
> 
> I like this idiom for certain situations, just wondering if it will
> raise the hackles of other Pythonistas.

I agree with Ned's comments -- the basic idea is fine, it's just caching 
some calculated result.

I often use this idiom in read-only properties, for something that only 
needs to be calculated once, but it's time-consuming to calculate and 
therefore I want to delay doing the calculation until the last possible 
minute. Something like this:

class Spam:
    @property
    def spam(self):
        try:
            result = self._spam
        except AttributeError:
            # Perform some time-consuming calculation.
            result = self._spam = \
                ("spam "*5).capitalize() + "LOVELY SPAM!!!!!"
        return result

but there are a million different variations on this theme.


> I use this idiom sparingly, but sometimes it just fits the task at hand,
> I hear Guidos voice saying "use the Force" in my ear, etc.

Good reasons for avoiding this pattern might include:

- the speed benefit is too trivial to justify the extra complexity;

- the risk that some condition will unexpectedly change, invalidating
  the cached value, but it's too hard to notice when the cache is 
  invalid;

- caching the result means you unnecessarily hold on to a chunk of
  memory which otherwise would be garbage collected (consider using
  weak references to solve this one);

but otherwise it is unobjectionable.


-- 
Steven



More information about the Python-list mailing list