OLD | NEW |
1 # Copyright (c) 2010 Google Inc. All rights reserved. | 1 # Copyright (c) 2010 Google Inc. All rights reserved. |
2 # | 2 # |
3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
5 # met: | 5 # met: |
6 # | 6 # |
7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
(...skipping 15 matching lines...) Expand all Loading... |
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 |
29 # Python does not (yet) seem to provide automatic memoization. So we've | 29 # Python does not (yet) seem to provide automatic memoization. So we've |
30 # written a small decorator to do so. | 30 # written a small decorator to do so. |
31 | 31 |
32 import functools | 32 import functools |
33 | 33 |
34 | 34 |
35 class memoized(object): | 35 class memoized(object): |
| 36 |
36 def __init__(self, function): | 37 def __init__(self, function): |
37 self._function = function | 38 self._function = function |
38 self._results_cache = {} | 39 self._results_cache = {} |
39 | 40 |
40 def __call__(self, *args): | 41 def __call__(self, *args): |
41 try: | 42 try: |
42 return self._results_cache[args] | 43 return self._results_cache[args] |
43 except KeyError: | 44 except KeyError: |
44 # If we didn't find the args in our cache, call and save the results
. | 45 # If we didn't find the args in our cache, call and save the results
. |
45 result = self._function(*args) | 46 result = self._function(*args) |
46 self._results_cache[args] = result | 47 self._results_cache[args] = result |
47 return result | 48 return result |
48 # FIXME: We may need to handle TypeError here in the case | 49 # FIXME: We may need to handle TypeError here in the case |
49 # that "args" is not a valid dictionary key. | 50 # that "args" is not a valid dictionary key. |
50 | 51 |
51 # Use python "descriptor" protocol __get__ to appear | 52 # Use python "descriptor" protocol __get__ to appear |
52 # invisible during property access. | 53 # invisible during property access. |
53 def __get__(self, instance, owner): | 54 def __get__(self, instance, owner): |
54 # Return a function partial with obj already bound as self. | 55 # Return a function partial with obj already bound as self. |
55 return functools.partial(self.__call__, instance) | 56 return functools.partial(self.__call__, instance) |
OLD | NEW |