【函數】06、裝飾器的應用
阿新 • • 發佈:2017-06-19
裝飾器
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、裝飾器的應用