author | Alberto Bertogli
<albertogli@telpin.com.ar> 2006-06-18 18:29:08 UTC |
committer | Alberto Bertogli
<albertogli@telpin.com.ar> 2006-06-18 18:29:08 UTC |
parent | 06e48cb21c32890dac3da841e58bf902138d5862 |
lazy.py | +54 | -0 |
samples/lazy/sample1.py | +19 | -0 |
diff --git a/lazy.py b/lazy.py new file mode 100644 index 0000000..b0d6c59 --- /dev/null +++ b/lazy.py @@ -0,0 +1,54 @@ + +""" +lazy - Decorators and utilities for lazy evaluation in Python +Alberto Bertogli (albertogli@telpin.com.ar) +""" + +class _LazyWrapper: + """Lazy wrapper class for the decorator defined below. + It's closely related so don't use it. + + We don't use a new-style class, otherwise we would have to implement + stub methods for __getattribute__, __hash__ and lots of others that + are inherited from object by default. This works too and is simple. + I'll deal with them when they become mandatory. + """ + def __init__(self, f, args, kwargs): + self._override = True + self._isset = False + self._value = None + self._func = f + self._args = args + self._kwargs = kwargs + self._override = False + + def _checkset(self): + if not self._isset: + self._override = True + self._value = self._func(*self._args, **self._kwargs) + self._isset = True + self._checkset = lambda: True + self._override = False + + def __getattr__(self, name): + if self.__dict__['_override']: + return self.__dict__[name] + self._checkset() + return getattr(self._value, name) + + def __setattr__(self, name, val): + if name == '_override' or self._override: + self.__dict__[name] = val + return + self._checkset() + setattr(self._value, name, val) + return + +def lazy(f): + "Lazy evaluation decorator" + def newf(*args, **kwargs): + return _LazyWrapper(f, args, kwargs) + + return newf + + diff --git a/samples/lazy/sample1.py b/samples/lazy/sample1.py new file mode 100644 index 0000000..91e898b --- /dev/null +++ b/samples/lazy/sample1.py @@ -0,0 +1,19 @@ + +import lazy +import time + + +def show(v): + print 'show() init + print' + s = str(v) + print 'show() v: ' + s + print 'show() done' + +@lazy.lazy +def set(): + print 'set() returns 3' + return 3 + +v = set() +show(v) +