前言
在Python中,裝飾器是一種十分強(qiáng)大并且好用的語(yǔ)法,一些重復(fù)的代碼使用裝飾器語(yǔ)法的話(huà)能夠使代碼更容易理解及閱讀。
因此在這里簡(jiǎn)單總結(jié)了一下Python中裝飾器的幾種用法以及需要注意的事情。
一、在裝飾器中獲取被裝飾函數(shù)的參數(shù)
假設(shè)我們?cè)陂_(kāi)發(fā)web的時(shí)候,需要做反爬。要判斷接口的訪問(wèn)來(lái)源我們就可以通過(guò)下面裝飾器的方法來(lái)實(shí)現(xiàn):
def mydecorator(func): def wrapped(*args, **kwargs): print("進(jìn)入裝飾器") if args[0]['header'] == 'spider': print("code: 400") return result = func(*args, **kwargs) return result return wrapped@mydecoratordef request_page(request): print("一個(gè)訪問(wèn)請(qǐng)求") print("返回了response")if __name__ == '__main__': request = { 'data': 100, 'header': 'spider' } request_page(request)
在這個(gè)裝飾器中,我們?cè)谘b飾器中獲取了request中的header參數(shù),如果判斷訪問(wèn)來(lái)源于爬蟲(chóng),那么便給它返回一個(gè)400。
使用裝飾器的寫(xiě)法等同于下面不使用裝飾器的寫(xiě)法
def mydecorator(*args, **kwargs): print("進(jìn)入函數(shù)") if args[0]['header'] == 'spider': print("code: 400") return False return Truedef request_page(request): if not mydecorator(request): return print("訪問(wèn)一個(gè)網(wǎng)頁(yè)") print("得到了response")if __name__ == '__main__': request = { 'data': 100, 'header': 'spider' } request_page(request)
在只需要裝飾一個(gè)函數(shù)的時(shí)候后面一種寫(xiě)法可能更優(yōu)于裝飾器的寫(xiě)法,但是在需要裝飾很多個(gè)函數(shù)的時(shí)候,使用裝飾器明顯是更好的選擇。
二、在裝飾器獲取函數(shù)的返回值
有的時(shí)候我們需要對(duì)函數(shù)的返回值做出判斷,但又不想直接將判斷寫(xiě)在函數(shù)里的時(shí)候,我們也可以使用裝飾器來(lái)實(shí)現(xiàn):
def mydecorator(func): def wrapped(*args, **kwargs): print("進(jìn)入裝飾器") result = func(*args, **kwargs) if result == 400: print("response is 400!") return False return True return wrapped@mydecoratordef request_page(): print("訪問(wèn)一個(gè)網(wǎng)頁(yè)") print("得到了response") return 200if __name__ == '__main__': print(request_page())
三、給裝飾器傳入?yún)?shù)
在實(shí)際應(yīng)用中,我們有時(shí)需要根據(jù)函數(shù)的執(zhí)行狀態(tài)來(lái)重復(fù)執(zhí)行。例如在編寫(xiě)爬蟲(chóng)的時(shí)候,可能由于網(wǎng)絡(luò)的原因會(huì)導(dǎo)致一些頁(yè)面訪問(wèn)失敗,這時(shí)我們就需要根據(jù)爬蟲(chóng)的返回結(jié)果進(jìn)行重復(fù)請(qǐng)求。
def retry(MAXRETRY=3): def decorator(func): def wrapped(*args, **kwargs): print("進(jìn)入裝飾器") 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("訪問(wèn)一個(gè)網(wǎng)頁(yè)") print("得到了response") return 400
在這里我們假設(shè)訪問(wèn)一個(gè)網(wǎng)頁(yè)得到400的時(shí)候便重新請(qǐng)求。我們?cè)趓etry裝飾器里傳了一個(gè)5,這表示我們希望重試的最大次數(shù)為5次,如果不傳入這個(gè)值,那么它的默認(rèn)重試次數(shù)則為3次。
在熟悉了基本裝飾器的寫(xiě)法后,傳參裝飾器的寫(xiě)法也十分的好理解了。就是在外面多加了一層函數(shù),用于傳入?yún)?shù)。
新聞熱點(diǎn)
疑難解答
圖片精選