Lazily-evaluated dictionaries.
from lazydict import LazyDictionary
lazy = LazyDictionary()
lazy['sum'] = lambda ld: ld['a'] + ld['b']
lazy['a'] = 1
lazy['b'] = 2
print lazy['sum']
# 3
A LazyDicitonary behaves mostly like an ordinary dict, except:
-
item values are frozen upon reading, and
-
values that are callable and take 1 or 0 arguments are called once before freezing
-
if the value takes 1 argument, the
LazyDictionaryinstance will be supplied as the argument. -
if calling the value raises an error, that error is frozen, and will be raised upon each subsequent read.
-
These features allow values in the dictionary to be dependent on other values in the dictionary without regard to order of assignment. It also allows lazily not executing unused code:
import tempfile
lazy = LazyDictionary()
lazy['temp'] = lambda: tempfile.mkdtemp()
If lazy['temp'] is never an R-value, mkdtemp() will never be called.
Callable 1-argument values are nodes in directed graphs. Edges are instances of
indexing the argument within the value's body. In the first example, sum is
the root and a and b are leaves. If a cycle exists in such a graph and a
node within the cycle is evaluated, a CircularReferenceError will be thrown
when the node is evaluated a second time.
If a frozen value is updated, a ConstantRedefinitionError will be thrown.
from lazydict import MutableLazyDictionary
A MutableLazyDictionary behaves mostly like a LazyDictionary, except that
its item values are not frozen when they are read.
pip install --pre lazydict
python setup.py test
