Я хотел реализовать ленивую загрузку переменных, но мне кажется, что я немного неправильно понимаю дескрипторы. Я хотел бы иметь объектные переменные, которые при первом доступе вызовут функцию obj.load (), которая инициализирует переменные с их реальным значением. Я написал
class ToLoad(object):
def __init__(self, loader_name="load")
self.loader_name=loader_name
def __get__(self, obj, type):
if not (hasattr(obj, "_loaded") and obj._loaded):
obj._loaded=True
getattr(obj, self.loader_name)()
return None
class Test(object):
x=ToLoad()
def __init__(self, y):
self.y=y
def load(self):
print("Loading {}".format(self.y))
self.x=self.y
t1=Test(1)
t2=Test(2)
print("A", t1.x)
print("B", t2.x)
print("C", t1.x)
, который не может вернуть фактическое значение при загрузке хотя бы в первый раз. Может ли кто-нибудь предложить другой способ решения этой проблемы? Я не уверен, как вернуть правильное значение в get , поскольку в этот момент я не знаю, что атрибут называется «x»? Любой другой путь?
ЧЕРТ, не могу ответить на свой вопрос ... Так вот
РЕДАКТИРОВАТЬ:
Спасибо за вклад! Однако моя функция load () не возвращает саму переменную, поскольку она загружает много разных переменных. И я хочу минимизировать нотацию для использования отложенной загрузки. Вот я и придумал декоратор
class to_load:
def __init__(self, *vars, loader="load"):
self.vars=vars
self.loader=loader
def __call__(self, cls):
def _getattr(obj, attr):
if attr in self.vars:
getattr(obj, self.loader)()
return getattr(obj, attr)
else:
raise AttributeError
cls.__getattr__=_getattr
return cls
@to_load("a", "b")
class Test:
def load(self):
print("Loading")
self.a=1
self.b=2
t=Test()
print("Starting")
print(t.a)
print(t.b)
#print(t.c)
Это нормально? Я не уверен, что я что-то ломаю.