如何实现对象属性的延迟加载,即如果属性被访问但尚不存在,则调用一些应该加载这些属性的对象方法?
我的第一次尝试是
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
我将仅对某些属性名称进行lazyload。 由于我还没有做过很多元分类,我不确定这是不是正确的方法。 你会建议什么?
答案 0 :(得分:6)
看起来像一个简单的property
会更好地解决这个问题:
@property
def my_attribute():
if not hasattr(self, '_my_attribute'):
do_expensive_operation_to_get_attribute()
return self._my_attribute
答案 1 :(得分:0)
从lazy
看django/utils/functionals.py
https://docs.djangoproject.com/en/2.1/_modules/django/utils/functional