Skip to content

Instantly share code, notes, and snippets.

@JacobHayes
Created March 24, 2017 22:23
Show Gist options
  • Save JacobHayes/d28db982469e3793b83ffc089e55ebaf to your computer and use it in GitHub Desktop.
Save JacobHayes/d28db982469e3793b83ffc089e55ebaf to your computer and use it in GitHub Desktop.
Python lazy initialization mixin and decorator
""" Provides a base class that allows lazy initialization
"""
from functools import update_wrapper
class LazyInit(object):
_wrapped_object = None
_wrapped_object_base = None
_wrapped_object_initialized = False
# List of attributes to pass through to object.__getattribute__. We know they are set and should resolve to the
# LazyInit class.
attribute_whitelist = (
'__dict__',
'_wrapped_object',
'_wrapped_object_base',
'_wrapped_object_initialized',
'_wrapped_object_init',
'attribute_whitelist',
)
@staticmethod
def _wrapped_object_init(obj):
raise NotImplementedError
# Must override __getattribute__ since we're using update_wrapper, which updates the instance's __dict__
def __getattribute__(self, name):
whitelist = object.__getattribute__(self, 'attribute_whitelist')
if name in whitelist:
return object.__getattribute__(self, name)
if not self._wrapped_object_initialized:
init, object_base = self._wrapped_object_init, self._wrapped_object_base
self._wrapped_object = init(object_base)
update_wrapper(self, self._wrapped_object, assigned=('__module__', '__doc__'))
self._wrapped_object_initialized = True
return getattr(self._wrapped_object, name)
def lazy_init(obj, init):
class Stub(LazyInit):
_wrapped_object_base = obj
_wrapped_object_init = staticmethod(init)
return update_wrapper(Stub(), obj)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment