ho qualche modo di costruire una struttura di dati (da alcuni contenuto del file, per esempio):come caricare pigro una struttura di dati (python)
def loadfile(FILE):
return # some data structure created from the contents of FILE
modo che io possa fare le cose come
puppies = loadfile("puppies.csv") # wait for loadfile to work
kitties = loadfile("kitties.csv") # wait some more
print len(puppies)
print puppies[32]
Nell'esempio precedente, ho perso un sacco di tempo leggendo lo kitties.csv
e creando una struttura dati che non ho mai usato. Vorrei evitare questo spreco senza controllare costantemente if not kitties
ogni volta che voglio fare qualcosa. Mi piacerebbe essere in grado di fare
puppies = lazyload("puppies.csv") # instant
kitties = lazyload("kitties.csv") # instant
print len(puppies) # wait for loadfile
print puppies[32]
Quindi, se non sempre cerco di fare qualsiasi cosa con kitties
, loadfile("kitties.csv")
non viene mai chiamato.
C'è qualche modo standard per farlo?
Dopo aver giocato un po 'con esso, ho prodotto la seguente soluzione, che sembra funzionare correttamente ed è piuttosto breve. Ci sono delle alternative? Ci sono degli svantaggi nell'usare questo approccio che dovrei tenere a mente?
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)
Quale potrebbe essere ancora migliore è che se qualcosa di simile ha funzionato:
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)
Ma questo non funziona perché self
è locale. In realtà finisce per chiamare loadfile
ogni volta che fai qualcosa.
Si consiglia di proxy '__nonzero__' e altri metodi. – ephemient
@ephemient: sembra che una chiamata a '__nonzero__' passerà attraverso' __getattr__', quindi qual è il problema? –
Suppongo che sia un po 'meglio dire "se self.F non è None' piuttosto che' if not self.F' poiché 'loadfile (FILE)' * potrebbe * essere 0 o la stringa vuota. –