degal/utils.py
changeset 96 d9cf1e272e90
parent 84 891545a38a2b
child 109 66a01c0806f1
equal deleted inserted replaced
95:3b00bd676fc9 96:d9cf1e272e90
     2     Miscellaneous utilities
     2     Miscellaneous utilities
     3 """
     3 """
     4 
     4 
     5 import functools
     5 import functools
     6 
     6 
     7 class LazyProperty (property) :
     7 class LazyProperty (object) :
     8     """
     8     """
     9         Lazy-loaded cached properties.
     9         Lazy-loaded cached properties.
    10 
    10 
    11         This functions by overriding the class's property attribute with the actual value attribute in the instance's
    11         This functions by overriding the class's property attribute with the actual value attribute in the instance's
    12         dict, causing all future attribute lookups to return that directly.
    12         dict, causing all future attribute lookups to return that directly.
       
    13 
       
    14         >>> class Foo (object) :
       
    15         ...     counter = 0
       
    16         ...     @lazy_load
       
    17         ...     def foo (self) :
       
    18         ...             self.counter += 1
       
    19         ...             return self.counter
       
    20         ... 
       
    21         >>> foo = Foo(); foo.foo, foo.foo, foo.counter
       
    22         (1, 1, 1)
       
    23 
    13     """
    24     """
    14 
    25 
    15     def __init__ (self, func) :
    26     def __init__ (self, func) :
    16         """
    27         """
    17             Initialize with no value
    28             Initialize with no value
    18         """
    29         """
    19 
       
    20         super(LazyProperty, self).__init__(func)
       
    21         
    30         
    22         # the getter function
    31         # the getter function
    23         self.func = func
    32         self.func = func
    24 
    33 
    25         # the attribute name
    34         # the attribute name
    36  
    45  
    37     def store (self, obj, value) :
    46     def store (self, obj, value) :
    38         """
    47         """
    39             Store the cached value, overring ourself
    48             Store the cached value, overring ourself
    40         """
    49         """
    41         
    50 
       
    51 #        print "[%x] %r.__dict__[%r] = %r" % (id(obj), obj, self.name, value)
       
    52 
    42         obj.__dict__[self.name] = value
    53         obj.__dict__[self.name] = value
    43 
    54 
    44     def __get__ (self, obj, owner) :
    55     def __get__ (self, obj, owner) :
    45         """
    56         """
    46             Generate the value, store it as the attribute and return it.
    57             Generate the value, store it as the attribute and return it.
    47         """
    58         """
    48         
    59 
    49         # compute value
    60         # compute value
    50         value = self.run(obj)
    61         value = self.run(obj)
    51 
    62 
    52         # store it
    63         # store it
    53         self.store(obj, value)
    64         self.store(obj, value)
    54         
    65         
    55         # return it
    66         # return it
    56         return value
    67         return value
    57 
    68     
    58 class LazyIteratorProperty (LazyProperty) :
    69 class LazyIteratorProperty (LazyProperty) :
    59     """
    70     """
    60         A lazy-loaded property that automatically converts an iterator/genexp into a list.
    71         A lazy-loaded property that automatically converts an iterator/genexp into a list.
    61     """
    72     """
    62 
    73 
    63     def run (self, obj) :
    74     def run (self, obj) :
    64         """
    75         """
    65             Wrap LazyProperty.run to return a list
    76             Wrap LazyProperty.run to return a list
    66         """
    77         """
    67 
    78 
    68         return list(super(LazyIteratorProperty, self).run(obj))
    79         return list(self.func(obj))
    69 
    80 
    70 lazy_load = LazyProperty
    81 lazy_load = LazyProperty
    71 lazy_load_iter = LazyIteratorProperty
    82 lazy_load_iter = LazyIteratorProperty
    72 
    83 
       
    84 # testing
       
    85 if __name__ == '__main__' :
       
    86     import doctest
       
    87 
       
    88     doctest.testmod()
       
    89