前言
在Python中,裝飾器是一種十分強大并且好用的語法,一些重復的代碼使用裝飾器語法的話能夠使代碼更容易理解及閱讀。
因此在這里簡單總結了一下Python中裝飾器的幾種用法以及需要注意的事情。
一、在裝飾器中獲取被裝飾函數的參數
假設我們在開發web的時候,需要做反爬。要判斷接口的訪問來源我們就可以通過下面裝飾器的方法來實現:
def mydecorator(func): def wrapped(*args, **kwargs): print("進入裝飾器") if args[0]['header'] == 'spider': print("code: 400") return result = func(*args, **kwargs) return result return wrapped@mydecoratordef request_page(request): print("一個訪問請求") print("返回了response")if __name__ == '__main__': request = { 'data': 100, 'header': 'spider' } request_page(request)
在這個裝飾器中,我們在裝飾器中獲取了request中的header參數,如果判斷訪問來源于爬蟲,那么便給它返回一個400。
使用裝飾器的寫法等同于下面不使用裝飾器的寫法
def mydecorator(*args, **kwargs): print("進入函數") if args[0]['header'] == 'spider': print("code: 400") return False return Truedef request_page(request): if not mydecorator(request): return print("訪問一個網頁") print("得到了response")if __name__ == '__main__': request = { 'data': 100, 'header': 'spider' } request_page(request)
在只需要裝飾一個函數的時候后面一種寫法可能更優于裝飾器的寫法,但是在需要裝飾很多個函數的時候,使用裝飾器明顯是更好的選擇。
二、在裝飾器獲取函數的返回值
有的時候我們需要對函數的返回值做出判斷,但又不想直接將判斷寫在函數里的時候,我們也可以使用裝飾器來實現:
def mydecorator(func): def wrapped(*args, **kwargs): print("進入裝飾器") result = func(*args, **kwargs) if result == 400: print("response is 400!") return False return True return wrapped@mydecoratordef request_page(): print("訪問一個網頁") print("得到了response") return 200if __name__ == '__main__': print(request_page())
三、給裝飾器傳入參數
在實際應用中,我們有時需要根據函數的執行狀態來重復執行。例如在編寫爬蟲的時候,可能由于網絡的原因會導致一些頁面訪問失敗,這時我們就需要根據爬蟲的返回結果進行重復請求。
def retry(MAXRETRY=3): def decorator(func): def wrapped(*args, **kwargs): print("進入裝飾器") result = 0 retry = 1 while result != 200 and retry <= MAXRETRY: result = func(*args, **kwargs) print("重試第%s次" % retry) retry += 1 return result return wrapped return decorator @retry(5)def request_page(): print("訪問一個網頁") print("得到了response") return 400
在這里我們假設訪問一個網頁得到400的時候便重新請求。我們在retry裝飾器里傳了一個5,這表示我們希望重試的最大次數為5次,如果不傳入這個值,那么它的默認重試次數則為3次。
在熟悉了基本裝飾器的寫法后,傳參裝飾器的寫法也十分的好理解了。就是在外面多加了一層函數,用于傳入參數。
新聞熱點
疑難解答