Reduce the overhead of functools.lru_cache for functions with no parameters

[Tom Forbes]

_obj = None
def get_obj():
   global _obj
   if _obj is None:
     _obj = create_some_object()
  return _obj

i.e lazy initialization of an object of some kind, with no parameters.

Eiffel uses the keyword “ONCE” for this. I would prefer a similar
approach, using a specialised decorator, rather than to special-case
lru_cache:

@once
def get_obj():
    obj = Something()
    obj.extras = None
    return obj

Here’s an untested implementation:

def once(func):
    obj = None
    @functools.wraps(func)
    def inner():
        nonlocal obj
        if obj is None:
            obj = func()
        return obj
    return inner