首页 > 代码库 > 【函数】06、装饰器的应用

【函数】06、装饰器的应用

1、写一个装饰器,实现缓存功能,允许过期,但没有换出,没有清除

 1)cache的必要元素:key --> value

     这里的key是函数的参数,value是函数的返回值


 2)超时时间

    超时时间如何存储


步骤1:

In [28]: from functools import wraps

In [29]: def cache(fn):
    ...:     cache_dict = {}
    ...:     @wraps                     
    ...:     def wraps(*args, **kwargs):     
    ...:         # 如何拼装key               
    ...:         if key in cache_dict.keys():
    ...:             # 如何实现超时检测      
    ...:             return cache_dict[key]  
    ...:         result = fn(*args, **kwargs)
    ...:         cache_dict[key] = result
    ...:         return result
    ...:     reutrn wraps

如何拼装key?

    参数名 + 参数值

    这里需要用到inspect库


标准库inspect的用法:

In [1]: import inspect

In [2]: def add(x, y):
   ...:     return x + Y
   ...: 

In [3]: inspect.signature
Out[3]: <function inspect.signature>

In [4]: inspect.signature(add)
Out[4]: <Signature (x, y)>

In [5]: sig = inspect.signature(add)  # 获取到函数的签名

In [17]: sig.parameters
Out[17]: mappingproxy({‘x‘: <Parameter "x">, ‘y‘: <Parameter "y">})

In [18]: for k in sig.parameters.keys():  # 获取参数
    ...:     print(k)
    ...:     
x
y


步骤2:

In [30]: from functools import wraps

In [31]: import inspect

In [32]: def cache(fn):             
    ...:     cache_dict = {}
    ...:     @wraps
    ...:     def wraps(*args, **kwargs):
    ...:         key = []     
    ...:         params = inspect.Signature(fn).parameters
    ...:         for i, arg in enumerate(args):                        
    ...:             # 位置参数的名(行参x或y)和其值(实参)                            
    ...:             name = list(params.keys())[i]                     
    ...:             key.append((name, arg))      
    ...:         key.extends(kwargs.items())    
    ...:         # 拼接KEY                      
    ...:         key.sort(key=lambda x: x[0] 
    ...:         key = ‘&‘.join([‘{}={}‘.format(name, arg) for name, arg in key])
    ...:                                     
    ...:         if key in cache_dict.keys():
    ...:             # 如何实现超时检测      
    ...:             return cache_dict[key]  
    ...:         result = fn(*args, **kwargs)
    ...:         cache_dict[key] = result
    ...:         return result
    ...:     reutrn wraps

当被装饰的函数有默认参数时,造成key不一样,不走cache,怎么处理?


步骤3:






2、写一个装饰器,实现命令分发器,用户输入指令,执行相应的函数

【函数】06、装饰器的应用