如何实现对象属性的延迟加载,即如果属性被访问但尚不存在,某些对象方法被调用,应该加载这些属性?延迟加载属性
我第一次尝试是
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具体到只有特定的属性名称。 由于我还没有做过很多元分类,我不确定这是否是正确的方法。 你会建议什么?
*“元类是用户的法宝不是更深层次的99%应该永远不用担心如果你想知道你是否需要他们,你不这样做。 “ - TP *。我认为丹尼尔建议的财产会更好。 – 2012-02-14 10:58:05
我正在使用这个食谱http://code.activestate.com/recipes/576563-cached-property/ – reclosedev 2012-02-14 14:56:57
@Rik:我不是在想我是否需要元类,而是如何解决lazyload问题。 Daniels的例子还没有完全解决它,因为它是只读的,我不希望每次出现重复的代码行。它可以调整吗? – Gerenuk 2012-02-15 09:44:43