Created
January 11, 2013 03:44
-
-
Save ali01/4507790 to your computer and use it in GitHub Desktop.
Function that returns a decorator to memoize stateless functions. Args: secs - Amount of time (in seconds) to keep values in the cache; the argument may be a floating point number to indicate a more precise timeout.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import functools | |
import hashlib | |
import time | |
def memoize(secs=0): | |
'''Returns a decorator to memoize stateless functions. | |
Args: secs - Amount of time (in seconds) to keep values in the cache; | |
The argument may be a floating point number to indicate a | |
more precise timeout. | |
''' | |
def decorator(f): | |
cache = {} | |
@functools.wraps(f) | |
def wrapped(*args, **kwargs): | |
args_hash = hash(args) | |
kwargs_keys_hash = hash(frozenset(kwargs.keys())) | |
kwargs_vals_hash = hash(frozenset(kwargs.values())) | |
m = hashlib.sha1() | |
m.update(str(args_hash)) | |
m.update(str(kwargs_keys_hash)) | |
m.update(str(kwargs_vals_hash)) | |
key = m.hexdigest() | |
time_now = time.time() if secs > 0 else 0 | |
if key not in cache: | |
# store value along with expire_time in cache | |
value = f(*args, **kwargs) | |
cache[key] = (value, time_now + secs) | |
elif secs > 0: | |
# refresh cache | |
expire_time = cache[key][1] | |
if time_now > expire_time: | |
value = f(*args, **kwargs) | |
cache[key] = (value, time_now + secs) | |
return cache[key][0] | |
return wrapped | |
return decorator |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment