У меня есть способ построить структуру данных (скажем, из содержимого какого-то файла):
def loadfile(FILE):
return # some data structure created from the contents of FILE
Итак Я могу делать такие вещи, как
puppies = loadfile("puppies.csv") # wait for loadfile to work
kitties = loadfile("kitties.csv") # wait some more
print len(puppies)
print puppies[32]
В приведенном выше примере Я потратил кучу времени на чтение kitties.csv
и создание структуры данных, которую никогда не использовал. Я бы хотел избежать этой траты, не проверяя если не котят
постоянно, когда я хочу что-то сделать. Я хотел бы иметь возможность делать
puppies = lazyload("puppies.csv") # instant
kitties = lazyload("kitties.csv") # instant
print len(puppies) # wait for loadfile
print puppies[32]
. Поэтому, если я когда-нибудь не попытаюсь что-нибудь сделать с kitties
, loadfile ("kitties.csv")
никогда не будет вызван.
Есть ли какой-нибудь стандартный способ сделать это?
Немного поигравшись с ним, я создал следующее решение, которое работает правильно и довольно кратко. Есть ли альтернативы? Есть ли недостатки в использовании этого подхода, о которых я должен помнить?
class lazyload:
def __init__(self,FILE):
self.FILE = FILE
self.F = None
def __getattr__(self,name):
if not self.F:
print "loading %s" % self.FILE
self.F = loadfile(self.FILE)
return object.__getattribute__(self.F, name)
Что могло бы быть еще лучше, если бы что-то вроде этого работало:
class lazyload:
def __init__(self,FILE):
self.FILE = FILE
def __getattr__(self,name):
self = loadfile(self.FILE) # this never gets called again
# since self is no longer a
# lazyload instance
return object.__getattribute__(self, name)
Но это не работает, потому что self
является локальным. Фактически, он вызывает loadfile
каждый раз, когда вы что-то делаете.