title: How to lazy load a data structure (python)
body: <p>I have some way of building a data structure (out of some file contents, say):</p>
  
  <pre><code>def loadfile(FILE):
      return # some data structure created from the contents of FILE
  </code></pre>
  
  <p>So I can do things like</p>
  
  <pre><code>puppies = loadfile("puppies.csv") # wait for loadfile to work
  kitties = loadfile("kitties.csv") # wait some more
  print len(puppies)
  print puppies[32]
  </code></pre>
  
  <p>In the above example, I wasted a bunch of time actually reading <code>kitties.csv</code> and creating a data structure that I never used. I'd like to avoid that waste without constantly checking <code>if not kitties</code> whenever I want to do something. I'd like to be able to do</p>
  
  <pre><code>puppies = lazyload("puppies.csv") # instant
  kitties = lazyload("kitties.csv") # instant
  print len(puppies)                # wait for loadfile
  print puppies[32]
  </code></pre>
  
  <p>So if I don't ever try to do anything with <code>kitties</code>, <code>loadfile("kitties.csv")</code> never gets called.</p>
  
  <p><strong>Is there some standard way to do this?</strong></p>
  
  <p>After playing around with it for a bit, I produced the following solution, which appears to work correctly and is quite brief. Are there some alternatives? Are there drawbacks to using this approach that I should keep in mind?</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>What might be even better is if something like this worked:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>But this doesn't work because <code>self</code> is local. It actually ends up calling <code>loadfile</code> every time you do anything. </p>