@@ -80,62 +80,6 @@ def evalform_back(val, form):
80
80
return reduce (evalform_back , forms , val )
81
81
82
82
83
- def memoize (func , cache = None ):
84
- """ Cache a function's result for speedy future evaluation
85
-
86
- Considerations:
87
- Trades memory for speed.
88
- Only use on pure functions.
89
-
90
- >>> def add(x, y): return x + y
91
- >>> add = memoize(add)
92
-
93
- Or use as a decorator
94
-
95
- >>> @memoize
96
- ... def add(x, y):
97
- ... return x + y
98
- """
99
- if cache is None :
100
- cache = {}
101
-
102
- try :
103
- spec = inspect .getargspec (func )
104
- may_have_kwargs = bool (not spec or spec .keywords or spec .defaults )
105
- # Is unary function (single arg, no variadic argument or keywords)?
106
- is_unary = (spec and spec .varargs is None and not may_have_kwargs
107
- and len (spec .args ) == 1 )
108
- except TypeError :
109
- may_have_kwargs = True
110
- is_unary = False
111
-
112
- def memof (* args , ** kwargs ):
113
- try :
114
- if is_unary :
115
- key = args [0 ]
116
- elif may_have_kwargs :
117
- key = (args , frozenset (kwargs .items ()))
118
- else :
119
- key = args
120
- in_cache = key in cache
121
- except TypeError :
122
- raise TypeError ("Arguments to memoized function must be hashable" )
123
-
124
- if in_cache :
125
- return cache [key ]
126
- else :
127
- result = func (* args , ** kwargs )
128
- cache [key ] = result
129
- return result
130
-
131
- try :
132
- memof .__name__ = func .__name__
133
- except AttributeError :
134
- pass
135
- memof .__doc__ = func .__doc__
136
- return memof
137
-
138
-
139
83
def _num_required_args (func ):
140
84
""" Number of args for func
141
85
@@ -239,6 +183,71 @@ def __call__(self, *args, **_kwargs):
239
183
return curry (self .func , * args , ** kwargs )
240
184
241
185
186
+ @curry
187
+ def memoize (func , cache = None ):
188
+ """ Cache a function's result for speedy future evaluation
189
+
190
+ Considerations:
191
+ Trades memory for speed.
192
+ Only use on pure functions.
193
+
194
+ >>> def add(x, y): return x + y
195
+ >>> add = memoize(add)
196
+
197
+ Or use as a decorator
198
+
199
+ >>> @memoize
200
+ ... def add(x, y):
201
+ ... return x + y
202
+
203
+ Use the ``cache`` keyword to provide a dict-like object as an initial cache
204
+
205
+ >>> @memoize(cache={(1, 2): 3})
206
+ ... def add(x, y):
207
+ ... return x + y
208
+
209
+ Note that the above works as a decorator because ``memoize`` is curried.
210
+ """
211
+ if cache is None :
212
+ cache = {}
213
+
214
+ try :
215
+ spec = inspect .getargspec (func )
216
+ may_have_kwargs = bool (not spec or spec .keywords or spec .defaults )
217
+ # Is unary function (single arg, no variadic argument or keywords)?
218
+ is_unary = (spec and spec .varargs is None and not may_have_kwargs
219
+ and len (spec .args ) == 1 )
220
+ except TypeError :
221
+ may_have_kwargs = True
222
+ is_unary = False
223
+
224
+ def memof (* args , ** kwargs ):
225
+ try :
226
+ if is_unary :
227
+ key = args [0 ]
228
+ elif may_have_kwargs :
229
+ key = (args , frozenset (kwargs .items ()))
230
+ else :
231
+ key = args
232
+ in_cache = key in cache
233
+ except TypeError :
234
+ raise TypeError ("Arguments to memoized function must be hashable" )
235
+
236
+ if in_cache :
237
+ return cache [key ]
238
+ else :
239
+ result = func (* args , ** kwargs )
240
+ cache [key ] = result
241
+ return result
242
+
243
+ try :
244
+ memof .__name__ = func .__name__
245
+ except AttributeError :
246
+ pass
247
+ memof .__doc__ = func .__doc__
248
+ return memof
249
+
250
+
242
251
class Compose (object ):
243
252
""" A composition of functions
244
253
0 commit comments