"""
Miscellaneous utilities
"""
import functools
class LazyProperty (property) :
"""
Lazy-loaded cached properties.
This functions by overriding the class's property attribute with the actual value attribute in the instance's
dict, causing all future attribute lookups to return that directly.
"""
def __init__ (self, func) :
"""
Initialize with no value
"""
super(LazyProperty, self).__init__(func)
# the getter function
self.func = func
# the attribute name
self.name = func.__name__
def run (self, obj) :
"""
Run the background func and return the to-be-cached value.
`obj` is the object instance
"""
return self.func(obj)
def store (self, obj, value) :
"""
Store the cached value, overring ourself
"""
obj.__dict__[self.name] = value
def __get__ (self, obj, owner) :
"""
Generate the value, store it as the attribute and return it.
"""
# compute value
value = self.run(obj)
# store it
self.store(obj, value)
# return it
return value
class LazyIteratorProperty (LazyProperty) :
"""
A lazy-loaded property that automatically converts an iterator/genexp into a list.
"""
def run (self, obj) :
"""
Wrap LazyProperty.run to return a list
"""
return list(super(LazyIteratorProperty, self).run(obj))
lazy_load = LazyProperty
lazy_load_iter = LazyIteratorProperty