Comment implémenteriez-vous une charge paresseuse d'attributs d'objet, c'est-à-dire si des attributs sont accédés mais n'existent pas encore, une méthode d'objet est appelée, qui est supposée les charger?Chargement paresseux des attributs
Ma première tentative est
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
Je ferai lazyload spécifiques à certains noms d'attributs seulement. Comme je n'ai pas encore fait beaucoup de méta-classification, je ne suis pas sûr que ce soit la bonne approche. Que suggérez-vous?
* "Métaclasses sont plus profondes magique Si vous vous demandez si vous avez besoin de 99% des utilisateurs ne devrait jamais se soucier, vous ne le faites pas.. " - TP *. Je pense qu'une propriété telle que suggérée par Daniel serait meilleure. –
J'utilise cette recette http://code.activestate.com/recipes/576563-cached-property/ – reclosedev
@Rik: Je ne me demande pas si j'ai besoin de méta-classes, mais plutôt, comment résoudre le problème de lazyload. L'exemple de Daniels ne le résout pas encore, puisqu'il est en lecture seule et que je ne veux pas de lignes de code en double pour chaque occurrence. Peut-il être ajusté? – Gerenuk