Skip to content

Instantly share code, notes, and snippets.

@sp3c73r2038
Last active December 21, 2015 17:19
Show Gist options
  • Save sp3c73r2038/6339845 to your computer and use it in GitHub Desktop.
Save sp3c73r2038/6339845 to your computer and use it in GitHub Desktop.
lazy loading property decorator and Lazy class.
#
# lazy loading decorator and class, idea stolen from ruby's lazy class and
# http://stackoverflow.com/questions/3012421/python-lazy-property-decorator
#
from __future__ import print_function
#
# lazy loading decorator for class property
#
def lazyprop(fn):
attr_name = '_' + fn.__name__
@property
def _lazyprop(inst):
if not inst._loaded:
print('lazy loading...')
obj = inst.lazy_source()
inst.__dict__.update(obj.__dict__)
# setattr(inst, '_loaded', True)
return getattr(inst, attr_name)
return _lazyprop
#
# Lazy class, for lazy object, add @lazyprop decorator to properties.
# Note that class must have `lazy_source` implemented to load real data
#
class Lazy(object):
_loaded = False
def __init__(self):
self._loaded = True
def lazy_source(self):
raise NotImplementedError()
@classmethod
def create(klass):
inst = klass.__new__(klass)
inst._loaded = False
return inst
class Foo(Lazy):
def __init__(self, name):
super(Foo, self).__init__()
self._name = name
@lazyprop
def name(self):
return self._name
def lazy_source(self):
# do some heavy loading here
return Foo.load_data()
@staticmethod
def load_data():
# real loading function
foo = Foo(name='foo')
return foo
print("\n\n\n\n===========\n\n\n\n")
foo = Foo.create()
print(foo)
print(foo.__dict__)
print(foo.name)
print(foo.__dict__)
print("\n\n\n\n===========\n\n\n\n")
foo = Foo(name='foobar')
print(foo.name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment