裝飾器概念,有什麼功能,及業務場景?

概念:

1.裝飾器的實現是由閉包支撐的;

2.裝飾器本質上是⼀個python函數,它可以在讓其他函數在不需要做任何代碼的變動的前提下增加額外的功能;

3.裝飾器的返回值也是⼀個函數的對象,它經常用於有切面需求的場景,實現路由傳參,flask的路由傳參依賴於裝飾器,瀏覽器通過url訪問到裝飾器的路由,從而訪問視圖函數獲得返回的HTML頁面;

應用場景:

1.可以在外層函數加上時間計算函數,計算函數運行時間;

2.計算函數運行次數;

3.可以用在框架的路由傳參上;

4.插入日誌,作爲函數的運行日誌;

5.事務處理,可以讓函數實現事務的一致性,讓函數要麼一起運行成功,要麼一起運行失敗;

6.緩存,實現緩存處理;

7.權限的校驗,在函數外層套上權限校驗的代碼,實現權限校驗;

 

寫出一個單例的裝飾器(使一個本來不是單例類的類變成單例類))

[python] view plain copy
  1. def set_func(func):  
  2.     __singleton = None  
  3.   
  4.     def call_func(*args, **kwargs):  
  5.         nonlocal __singleton  
  6.         if not __singleton:  
  7.             __singleton = func(*args, **kwargs)  
  8.             return __singleton  
  9.         else:  
  10.             return __singleton  
  11.     return call_func  
  12.  
  13.  
  14. @set_func  
  15. class Std(object):  
  16.   
  17.     def __init__(self, name, age):  
  18.         self.name = name  
  19.         self.age = age  
  20.   
  21.   
  22. s2 = Std('jack',18)  
  23. print(id(s2),s2.name,s2.age)  
  24.   
  25. s1 = Std('leo',23)  
  26. print(id(s1),s1.name,s1.age)  

運行結果:

[python] view plain copy
  1. 139727292442832 jack 18  
  2. 139727292442832 jack 18  

上下文提供者(Context Provider)

上下文裝飾器被用來確保函數在正確的上下文環境運行,或者確保在函數運行前和運行後執行一些代碼。換言之,該裝飾器進行設置或取消設置某個特定的運行環境。例如,當一條數據要在多個線程之間共享時,就需要使用鎖(lock)來確保數據被保護,以防出現併發訪問。鎖能夠像下面這樣放在裝飾器

上下文裝飾器,通常被上下文管理器(with 語句)取代。
from threading import RLock
lock = RLock()
def synchronized(function):
    def _synchronized(*args, **kw):
        lock.acquire()
        try:
            return function(*args, **kw)
        finally:
            lock.release()
    return _synchronized
 
@synchronized
def thread_safe(): # make sure it locks the resource
    pass

登錄判斷裝飾器:

    之前做過的一個用flask框架實現的移動app項目,裏面大量用到是否已經登錄的判斷,如果這個業務邏輯大量重複地寫在視圖函數,代碼的複用性很差,因此我將登錄判斷封裝成裝飾器,然後用這個裝飾器裝飾每一個需要驗證是否登錄的視圖函數,代碼如下:


[python] view plain copy
  1. def login_required(view_func):  
  2.     """自定義裝飾器判斷用戶是否登錄"""  
  3.  
  4.     @wraps(view_func)  
  5.     def wrapper(*args, **kwargs):  
  6.         """具體實現判斷用戶是否登錄的邏輯"""  
  7.         user_id = session.get('user_id')  
  8.         if not user_id:  
  9.             return jsonify(errno=RET.SESSIONERR, errmsg='用戶未登錄')  
  10.         else:  
  11.             g.user_id = user_id  
  12.             return view_func(*args, **kwargs)  
  13.   
  14.     return wrapper  
    總結:裝飾器是python三大神器(迭代器,生成器,裝飾器)中比較難理解的,但是它的本質實際上就是閉包,我們在閉包函數或者類外面封裝了一套邏輯,因此可以增強函數的功能,增加權限校驗,事務一致性,緩存等功能,這就是裝飾器,使漂亮的姑娘(函數)變得更加漂亮。
發佈了13 篇原創文章 · 獲贊 25 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章