lazy dictionary class

This commit is contained in:
Mike McLean 2010-05-25 19:20:36 -04:00
parent b56dec036c
commit 3ecb32cfcb

View file

@ -113,6 +113,73 @@ def dslice(dict, keys, strict=True):
return ret
class LazyValue(object):
"""Used to represent a value that is generated by a function call at access time
"""
def __init__(self, func, args, kwargs=None, cache=False):
if kwargs is None:
kwargs = {}
self.func = func
self.args = args
self.kwargs = kwargs
self.cache = cache
def get(self):
if hasattr(self, '_value'):
return self._value
value = self.func(*self.args, **self.kwargs)
if self.cache:
self._value = value
return value
def lazy_eval(value):
if isinstance(value, LazyValue):
return value.get()
return value
class LazyDict(dict):
"""A container for lazy data
fields can refer to function calls, which can optionally be cached
"""
def __getitem__(self, key):
return lazy_eval(super(LazyDict, self).__getitem__(key))
def lazyset(self, key, func, args, kwargs=None, cache=False):
self[key] = LazyValue(func, args, kwargs=kwargs, cache=cache)
def get(self, *args, **kwargs):
return lazy_eval(super(LazyDict, self).get(*args, **kwargs))
def copy(self):
return LazyDict(self)
def values(self):
return [lazy_eval(val) for val in super(LazyDict, self).values()]
def items(self):
return [(key, lazy_eval(val)) for key, val in super(LazyDict, self).items()]
def itervalues(self):
for val in super(LazyDict, self).itervalues():
yield lazy_eval(val)
def iteritems(self):
for key, val in super(LazyDict, self).iteritems():
yield key, lazy_eval(val)
def pop(self, key, *args, **kwargs):
return lazy_eval(super(LazyDict, self).pop(key, *args, **kwargs))
def popitem(self):
key, val = super(LazyDict, self).popitem()
return key, lazy_eval(val)
def rmtree(path):
"""Delete a directory tree without crossing fs boundaries"""
st = os.lstat(path)