marcus-g
5/17/2017 - 5:39 AM

Lazy evaluation is a useful pattern that can improve your code's efficiency in many situations. One example of this is instance attributes t

Lazy evaluation is a useful pattern that can improve your code's efficiency in many situations. One example of this is instance attributes that take long to compute. In this case, the list of relatives is only computed the first time Person#relatives is accessed. After that, it is stored in Person#_relatives to prevent repeated evaluations.

The other gist uses decorators to define a @lazy_property decorator that does the same thing. This reduces the amount of boilerplate in a class, especially if it uses alot of lazy properties. From http://stevenloria.com/lazy-evaluated-properties-in-python/

# Better
class Person:
  def __init__(self, name, occupation):
    self.name = name
    self.occupation = occupation
    self._relatives = []              
    
    @property
    def relatives(self):
      if not self._relatives:
        self._relatives = ... # Get all relatives
      return self._relatives
# Even better

def lazy_property(fn):
    '''Decorator that makes a property lazy-evaluated.
    '''
    attr_name = '_lazy_' + fn.__name__

    @property
    def _lazy_property(self):
        if not hasattr(self, attr_name):
            setattr(self, attr_name, fn(self))
        return getattr(self, attr_name)
    return _lazy_property

class Person:
    def __init__(self, name, occupation):
        self.name = name
        self.occupation = occupation
        
    @lazy_property
    def relatives(self):
        # Get all relatives
        relatives = ...
        return relatives