Lazy evaluation function decorator Suppose I have some expensive function expensive_computation which takes a long time to compute but it always returns the same value.

I want to avoid paying the cost of computing this function because it may never be called.

Here is my solution to this, is there a more obvious or clean way to do it? Or maybe even some function from the standard library? 

def lazy(function):

  internal_state = None

  def lazy_evaluation():
    nonlocal internal_state
    if internal_state is None:
      internal_state = function()
    return internal_state

  return lazy_evaluation

@lazy
def expensive_computation():
  print("Working ...")
  return "that was hard"

print(expensive_computation())
print(expensive_computation())


Which prints:

Working ...
that was hard
that was hard
if internal_state is None:
      internal_state = function()



What if function() returns None?




  Or maybe even some function from the standard library?


functools.lru_cache