AnyISalIn
7/25/2017 - 12:56 PM

cache.py

from functools import wraps
import inspect
import datetime

def cache(exp=0):
    def _cache(fn): ## fn cache
        cache = {}
        @wraps(fn)
        def wrap(*args, **kwargs):
            # TODO key 如何拼装
            key = []
            names = set()
            params = inspect.signature(fn).parameters
            for i, arg in enumerate(args):
                name = list(params.keys())[i]
                key.append((name, arg))
                names.add(name)
            key.extend(kwargs.items())
            names.update(kwargs.keys())
            for k, v in params.items():
                if k not in names:
                    key.append((k, v.default))
            key.sort(key=lambda x: x[0])
            key = '&'.join(['{}={}'.format(name, arg) for name, arg in key])
            print(key)
            if key in cache.keys():
                ret, timestamp = cache[key]
                if exp == 0 or datetime.datetime.now().timestamp() - timestamp < exp:
                    print('cache hit')
                    return ret
            ret = fn(*args, **kwargs)
            print('cache miss')
            cache[key] = (ret, datetime.datetime.now().timestamp())
            return ret
        return wrap
    return _cache