Created
October 13, 2010 22:59
-
-
Save robinhouston/625130 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class lazy(object): | |
'''A simple lazy evaluation hack, with just enough magic to be | |
useful for passing as a value to a Django template. | |
Creates a lazy wrapper around a function call, when used as | |
lazy(function, argument_1, argument_2, ...) | |
The resulting object is callable, and calling it (with no arguments) will | |
evaluate the function on the arguments passed to the constructor. | |
Trying to access the object in other ways (getting attributes, getting items, | |
iterating over it) will evaluate the function, if it hasn't already been evaluated, | |
and then delegate to the result. | |
The net effect is that the resulting "lazy" object can be used in a Django | |
template just as if it were the actual result of the function call, except | |
that the function will not be evaluated unless and until it is in fact so used. | |
''' | |
def __init__(self, f, *args, **kwargs): | |
self.__f, self.__args, self.__kwargs, self.__computed = f, args, kwargs, False | |
def __call__(self): | |
if not self.__computed: | |
self.__computed, self.__value = True, self.__f(*self.__args, **self.__kwargs) | |
return self.__value | |
def __getattribute__(self, name): | |
if name.startswith("_lazy__"): | |
return super(lazy, self).__getattribute__(name) | |
return getattr(self(), name) | |
def __iter__(self): | |
return iter(self()) | |
def __str__(self): | |
return str(self()) | |
def __nonzero__(self): | |
return bool(self()) | |
def __len__(self): | |
return len(self()) | |
def __getitem__(self, item): | |
return self().__getitem__(item) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment