How would you implement lazy load of object attributes, i.e. if attributes are accessed but don’t exist yet, some object method is called which is supposed to load these?
My first attempt is
def lazyload(cls):
def _getattr(obj, attr):
if "_loaded" not in obj.__dict__:
obj._loaded=True
try:
obj.load()
except Exception as e:
raise Exception("Load method failed when trying to access attribute '{}' of object\n{}".format(attr, e))
if attr not in obj.__dict__:
AttributeError("No attribute '{}' in '{}' (after loading)".format(attr, type(obj))) # TODO: infinite recursion if obj fails
return getattr(obj, attr)
else:
raise AttributeError("No attribute '{}' in '{}' (already loaded)".format(attr, type(obj)))
cls.__getattr__=_getattr
return cls
@lazyload
class Test:
def load(self):
self.x=1
t=Test() # not loaded yet
print(t.x) # will load as x isnt known yet
I will make lazyload specific to certain attribute names only.
As I havent done much meta-classing yet, I’m not sure if that is the right approach.
What would you suggest?
Seems like a simple
propertywould do the trick better: