Skip to content

Instantly share code, notes, and snippets.

@ali01
Created January 11, 2013 03:44
Show Gist options
  • Select an option

  • Save ali01/4507790 to your computer and use it in GitHub Desktop.

Select an option

Save ali01/4507790 to your computer and use it in GitHub Desktop.

Revisions

  1. ali01 created this gist Jan 11, 2013.
    46 changes: 46 additions & 0 deletions memoizer.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,46 @@
    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