属性的懒加载
你会怎么实现对象属性的懒加载呢?也就是说,当访问某些属性但它们还不存在时,应该调用某个对象的方法来加载这些属性。
我第一次尝试是这样的:
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
我打算只对某些特定的属性名进行懒加载。因为我还没有做过很多元类的相关工作,所以不太确定这样做是否正确。你有什么建议吗?
2 个回答
1
看看 django/utils/functionals.py
里的 lazy
。
https://docs.djangoproject.com/en/2.1/_modules/django/utils/functional
7
看起来用一个简单的 property
就能更好地解决这个问题:
@property
def my_attribute():
if not hasattr(self, '_my_attribute'):
do_expensive_operation_to_get_attribute()
return self._my_attribute