缓存装饰器的应用习题练习

import datetime

目前创新互联公司已为近1000家的企业提供了网站建设、域名、雅安服务器托管、网站托管维护、企业网站设计、吉州网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。

import inspect

from  inspect import signature,Parameter

def decrode_cache(fn):

    ##只是装饰器开始的时间

    local_cache={}

    def wrapper(*agrs, **kwargs):

        clear_list= []

        for k,(_,stamp) in local_cache.items():  ##此处意思是说 每次只要函数一调用一进来先遍历一次看看之前local_dict的时间戳,在和现在的进行比较

            star = datetime.datetime.now().timestamp()

        #如果已存在的时间戳和现在比较大于五秒,则清楚缓存(清楚缓存要明确清楚的是字典的key,values值,它是缓存)。

            if star - stamp >5:

                clear_list.append(k)

        for k in clear_list: #这里有一个知识点要注意 字典在遍历的过程中不能移除内容,有需要移除的可以先把他们存在列表里,然后在遍历列表pop字典的值

            local_cache.pop(k)

        paramers_dict = {} #构建一个装参数的空字典

    ##考虑 agrs 传参 要求 从参数字典中提取的name = args(按顺序等于) 组成一个k,v字典传给paramers_dict

        sig = inspect.signature(fn)

        parameters = sig._parameters #OrderedDict([('x', ), ('y', )])

    #从参数字典中提取的name = args(按顺序等于) 组成一个k,v字典

        params_name = [key for key in parameters.keys()]

        for i,values in enumerate(agrs):

            k = params_name[i]

            paramers_dict[k] = values

    #kwargs 所有值update 到参数字典中

        for k,v in kwargs.items():

            paramers_dict[k] = v

    #缺省值传参方式 add() 如果用缺省值则args kwargs都是空的 那就要把signatue.Paramers字典中的缺省值拿出来加到参数字典中来

        for k,v in parameters.items():

            if k not in parameters.keys():

                parameters[k]= v.default

    #三种情况都考虑周全后,该考虑排序问题 也就是要求的 add(x=3,y=4) 和 add(y=4,x=3)的问题

        new_paramers_dict = tuple(sorted(parameters)) #变成tuple的原因一方面是不可变位置,另一方面是需要把这个值缓存到本地字典中作为key,key必须是不可hash的值所以只能用元祖包装

        if new_paramers_dict  not in local_cache.keys(): ##所有的参数字典都搞定以后就要进行缓存了,缓存其实就是把参数字典写到本地字典中去,第二次输入相同的参数就可以在本地中直接取结果,如果是第一次创建没在本地中就写入。

            local_cache[new_paramers_dict] = (fn(*agrs,**kwargs),datetime.datetime.now().timestamp()) ##返回的是参数的解构 构造的是一个{("x"=3,"y"=4):7}的一个字典 前部分是key 是个元祖解构很少见要注意

        return local_cache[new_paramers_dict] ### 此处是k,v对创建的时间 也就是函数生成的时间,给此处打一个时间戳,记录他的生命周期的开始,函数再次输入时,这就是成为了过去式。(记住此处的巧妙用法,把时间付给values)

    return wrapper

import time

@decrode_cache

def add(x=1,y=2):# args(1,2) kwargs(x=1,x=2) default=()

    time.sleep(3)

    return x+y


标题名称:缓存装饰器的应用习题练习
标题URL:http://myzitong.com/article/piipej.html