Delay load/calculate values in Python
Question: Many times I run into the situation where I want a static/global/constant
variable that may take time to calculate, may be reused many times in a single
run, and may not be used at all during a single run.

One example would be a filter that I apply to an image that takes time to
calculate or load from disk, but is only used on some runs of the program (if
the filter was requested), but could be applied to many images during that
run.

How to accomplish this?


Answer: **Simple Method**

One solution is to have an init function for a module and call it whenever you
are about to enter code that uses the static constants. It in turn looks to
see if it has already calculated it, and if not, calculate it.

This doesn't seem Python-esque and seems like it could be encapsulate and made
reusable, reducing the manual checking of initialization and use of global
statement.

**Advanced Method**

I created a module that can make variables that behave just like the value
they are delay-loading, but they don't calculate the value until necessary.
The module can be found at:
<https://gist.github.com/coderforlife/de80081322d535582581>

Trivial Example:

    
    
    from delayed import delayed
    del_list = delayed(lambda: [1,2,3,4,5])
    # At this point the lambda function has not been called
    print(del_list[0])
    # Now that we have used the variable, the lambda has been called
    

More Advanced Example (better accomplished by pre-calculating the value, but
you get the idea):

    
    
    def __is_prime(p, primes):
        return all((p % prime != 0) for prime in primes)
    def __get_prime():
        primes = [3,5,7,11]
        for p in xrange(13, 50000, 2):
            if __is_prime(p, primes):
                primes.append(p)
        return primes[-1]
    prime = delayed(__get_prime, int)
    

This is accomplished by creating a new class for the delay-loaded object that
has all of the magic-methods of the underlying type and forwards other
attribute requests to the the underlying object. Whenever a magic-method or
attribute is requested, it loads the object is necessary then continues on.
Once the object is loaded, the loading function is 'deleted' so it can't go
through it again.

I have tested the module with lots of basic types and it works. I am sure that
are plenty of classes for which it doesn't work. I am willing to hear
suggestions for improvements.

