Classic memoize decorator for non-class methods

def memoize(func):
    """ Classic memoize decorator for non-class methods """
    cache = {}

    @functools.wraps(func)
    def wrapper(*args):
        key = "__".join(str(arg) for arg in args)
        if key not in cache:
            cache[key] = func(*args)
        return cache[key]
    return wrapper