(fun)
return wrapper
A simple memoize decorator for functions supporting (hashable)
    positional arguments.
    It also provides a cache_clear() function for clearing the cache:

    >>> @memoize
    ... def foo()
    ...     return 1
    ...
    >>> foo()
    1
    >>> foo.cache_clear()
    >>>
A simple memoize decorator for functions supporting (hashable)
    positional arguments.
    It also provides a cache_clear() function for clearing the cache:
A simple memoize decorator for functions supporting ( hashable ) positional arguments . It also provides a cache_clear () function for clearing the cache :
def memoize(fun):
    """A simple memoize decorator for functions supporting (hashable)
    positional arguments.
    It also provides a cache_clear() function for clearing the cache:

    >>> @memoize
    ... def foo()
    ...     return 1
    ...
    >>> foo()
    1
    >>> foo.cache_clear()
    >>>
    """
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):
        key = (args, frozenset(sorted(kwargs.items())))
        lock.acquire()
        try:
            try:
                return cache[key]
            except KeyError:
                ret = cache[key] = fun(*args, **kwargs)
        finally:
            lock.release()
        return ret

    def cache_clear():
        """Clear cache."""
        lock.acquire()
        try:
            cache.clear()
        finally:
            lock.release()

    lock = threading.RLock()
    cache = {}
    wrapper.cache_clear = cache_clear
    return wrapper
def memoize ( fun ) : @ functools . wraps ( fun ) def wrapper ( * args , * * kwargs ) : key = ( args , frozenset ( sorted ( kwargs . items ( ) ) ) ) lock . acquire ( ) try : try : return cache [ key ] except KeyError : ret = cache [ key ] = fun ( * args , * * kwargs ) finally : lock . release ( ) return ret def cache_clear ( ) : """Clear cache.""" lock . acquire ( ) try : cache . clear ( ) finally : lock . release ( ) lock = threading . RLock ( ) cache = { } wrapper . cache_clear = cache_clear return wrapper