1. 程式人生 > >【函數】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、裝飾器的應用