back

by jjgreen·10y ago·view on hn ↗
I've previously used hasattr() to check for the existence of an attribute qua instance variable to lazy-load and cache that attribute

    def kdtree(self):
      if not hasattr(self, '_kdtree'):
        self._kdtree = scipy.spatial.KDTree(self.xi.T)
      return self._kdtree

like ruby's

    @foo ||= expensive_calculation
is there a better way?
3 comments
Well, you can do it this way:

    def kdtree(self):
        try:
            return self._kdtree
        except AttributeError:
            pass
        self._kdtree = scipy.spatial.KDTree(self.xi.T)
        return self._kdtree
And, of course, you could do all of that with a decorator.
In this particular case you should initialize self._kdtree to None in __init__, and just check if self._kdtree is None: <calculate>
Works great unless None is a valid value for the thing, in which case you'll recalculate it every time. If that was the case you should just use hasattr().
Or try and except AttributeError. Exceptions are a good thing.
I went with this decorator in the end, works a treat! https://github.com/jjgreen/mvpoly/blob/master/src/python/mvp...
Ah, nice, thanks