Python-缓存应用之自定义缓存

实现一个cache装饰器,过期可被清理的功能

实现如下六种调用为同一种调用,实现缓存功能

 

 

import inspect
from functools import wraps
import datetime
import time


def logger(fn):
    @wraps(fn)
    def wrapper(*args,**kwargs):
        start = datetime.datetime.now()
        ret = fn(*args,**kwargs)
        delta = (datetime.datetime.now() - start).total_seconds()
        print(fn.__name__,delta)
        return ret
    return wrapper

def m_cache(duration):
    def _cache(fn):
        local_cache = {}
        @wraps(fn)
        def wrapper(*args,**kwargs):
            expire_keys = []
            for k,(_,stamp) in local_cache.items():
                now = datetime.datetime.now().timestamp()
                if now - stamp > duration:
                    expire_keys.append(k)
            for k in expire_keys:
                local_cache.pop(k)
                # print(expire_keys)

            #参数处理,构建key
            sig = inspect.signature(fn)
            params = sig.parameters
            names  = list(params.keys())
            target = {}

            #位置传参和关键字传参结合
            target.update(zip(params.keys(),args),**kwargs)

            #缺省参数处理
            target.update(((k,params[k].default) for k in (params.keys() - target.keys())))
            # print(target.items())

            key = tuple(sorted(target.items()))
            # print(key)


            #是否在缓存中
            if key not in local_cache.keys():
                local_cache[key] = fn(*args,**kwargs),datetime.datetime.now().timestamp()
            return local_cache[key]
        return wrapper
    return _cache



@logger
@m_cache(1)
def add(x=4,y=5):
    print('----------')
    time.sleep(1)
    return x + y

print(1,add(4,5))
print(2,add(4))
print(3,add(y=5))
time.sleep(2)
print(4,add(x=4,y=5))
print(5,add(y=5,x=4))
print(6,add())

 

将清理缓存抽象成函数

import inspect
from functools import wraps
import datetime
import time


def logger(fn):
    @wraps(fn)
    def wrapper(*args,**kwargs):
        start = datetime.datetime.now()
        ret = fn(*args,**kwargs)
        delta = (datetime.datetime.now() - start).total_seconds()
        print(fn.__name__,delta)
        return ret
    return wrapper

def m_cache(duration):
    def _cache(fn):
        local_cache = {}
        @wraps(fn)
        def wrapper(*args,**kwargs):
            def clear(cache):
                expire_keys = []
                for k,(_,stamp) in cache.items():
                    now = datetime.datetime.now().timestamp()
                    if now - stamp > duration:
                        expire_keys.append(k)
                for k in expire_keys:
                    cache.pop(k)
                    # print(expire_keys)
            clear(local_cache)
            #参数处理,构建key
            sig = inspect.signature(fn)
            params = sig.parameters
            names  = list(params.keys())
            target = {}

            #位置传参和关键字传参结合
            target.update(zip(params.keys(),args),**kwargs)

            #缺省参数处理
            target.update(((k,params[k].default) for k in (params.keys() - target.keys())))
            # print(target.items())

            key = tuple(sorted(target.items()))
            # print(key)


            #是否在缓存中
            if key not in local_cache.keys():
                local_cache[key] = fn(*args,**kwargs),datetime.datetime.now().timestamp()
            return local_cache[key]
        return wrapper
    return _cache



@logger
@m_cache(1)
def add(x=4,y=5):
    print('----------')
    time.sleep(1)
    return x + y

print(1,add(4,5))
print(2,add(4))
print(3,add(y=5))
time.sleep(2)
print(4,add(x=4,y=5))
print(5,add(y=5,x=4))
print(6,add())

 

posted @ 2020-05-07 22:20  Alrenn  阅读(613)  评论(0)    收藏  举报