Python如何合并多個裝飾器?教你幾個小技巧

成都創(chuàng)新互聯(lián)是專業(yè)的麥積網(wǎng)站建設(shè)公司,麥積接單;提供網(wǎng)站設(shè)計制作、成都網(wǎng)站建設(shè),網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行麥積網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊,希望更多企業(yè)前來合作!
django程序,需要寫很多api,每個函數(shù)都需要幾個裝飾器 ,例如
復(fù)制代碼 代碼如下:
@csrf_exempt
@require_POST
def foo(request):
pass
既然那么多個方法都需要寫2個裝飾器,或者多個,有啥辦法把多個合并成一行呢?
上面的函數(shù)執(zhí)行過程應(yīng)該是
復(fù)制代碼 代碼如下:
csrf_exempt(require_POST(foo))
修改成
復(fù)制代碼 代碼如下:
def compose(*funs):
def deco(f):
for fun in reversed(funs):
f = fun(f)
return f
return deco
函數(shù)改寫成
復(fù)制代碼 代碼如下:
@compose(csrf_exempt, require_POST)
def foo(request):
pass
參考:
Can I combine two decorators into a single one in Python
;
首先十分不推薦這種做法, 會令程序難以維護(hù).
其次, 多個裝飾器是按照裝飾器的順序進(jìn)行執(zhí)行的.
如果你編寫過裝飾器, 你就應(yīng)該知道, 其實(shí)裝飾器就是把函數(shù)的名字傳入進(jìn)去, 在執(zhí)行函數(shù)之前, 進(jìn)行一些提前的處理.
例如下面這段代碼, 自定義的裝飾器
def add_schedid(handler_func):
"""
@handler_func: 請求處理函數(shù)
"""
@functools.wraps(handler_func)
def wrapper(self, *args, **kwargs):
"""
wrapper
"""
# handler_func就是所裝飾的函數(shù),可以在這里做一些真正函數(shù)執(zhí)行前所需的處理,
handler_func(self, *args, **kwargs)
return wrapper
裝飾器本身就是一個函數(shù), 將所裝飾的函數(shù), 作為一個參數(shù)傳進(jìn)來, 然后在執(zhí)行這個函數(shù)之前, 進(jìn)行一個處理,這就是裝飾器. 所以和正常函數(shù)執(zhí)行順序是一樣的..
裝飾器是通過裝飾器函數(shù)修改原函數(shù)的一些功能而不需要修改原函數(shù),在很多場景可以用到它,比如① 執(zhí)行某個測試用例之前,判斷是否需要登錄或者執(zhí)行某些特定操作;② 統(tǒng)計某個函數(shù)的執(zhí)行時間;③ 判斷輸入合法性等。合理使用裝飾器可以極大地提高程序的可讀性以及運(yùn)行效率。本文將介紹Python裝飾器的使用方法。
python裝飾器可以定義如下:
輸出:
python解釋器將test_decorator函數(shù)作為參數(shù)傳遞給my_decorator函數(shù),并指向了內(nèi)部函數(shù) wrapper(),內(nèi)部函數(shù) wrapper() 又會調(diào)用原函數(shù) test_decorator(),所以decorator()的執(zhí)行會先打印'this is wrapper',然后打印'hello world', test_decorator()執(zhí)行完成后,打印 'bye' ,*args和**kwargs,表示接受任意數(shù)量和類型的參數(shù)。
裝飾器 my_decorator() 把真正需要執(zhí)行的函數(shù) test_decorator() 包裹在其中,并且改變了它的行為,但是原函數(shù) test_decorator() 不變。
一般使用如下形式使用裝飾器:
@my_decorator就相當(dāng)于 decorator = my_decorator(test_decorator) 語句。
內(nèi)置裝飾器@functools.wrap可用于保留原函數(shù)的元信息(將原函數(shù)的元信息,拷貝到對應(yīng)的裝飾器函數(shù)里)。先來看看沒有使用functools的情況:
輸出:
從上面的輸出可以看出test_decorator() 函數(shù)被裝飾以后元信息被wrapper() 函數(shù)取代了,可以使用@functools.wrap裝飾器保留原函數(shù)的元信息:
輸出:
裝飾器可以接受自定義參數(shù)。比如定義一個參數(shù)來設(shè)置裝飾器內(nèi)部函數(shù)的執(zhí)行次數(shù):
輸出:
Python 支持多個裝飾器嵌套:
裝飾的過程:
順序從里到外:
test_decorator('hello world') 執(zhí)行順序和裝飾的過程相反。
輸出:
類也可以作為裝飾器,類裝飾器主要依賴__call__()方法,是python中所有能被調(diào)用的對象具有的內(nèi)置方法(python魔術(shù)方法),每當(dāng)調(diào)用一個類的實(shí)例時,__call__()就會被執(zhí)行一次。
下面的類裝飾器實(shí)現(xiàn)統(tǒng)計函數(shù)執(zhí)行次數(shù):
輸出:
下面介紹兩種裝飾器使用場景
統(tǒng)計函數(shù)執(zhí)行所花費(fèi)的時間
輸出:
在使用某些web服務(wù)時,需要先判斷用戶是否登錄,如果沒有登錄就跳轉(zhuǎn)到登錄頁面或者提示用戶登錄:
--THE END--
文章題目:python多個裝飾函數(shù)的簡單介紹
分享路徑:http://chinadenli.net/article28/dsgsgjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊、網(wǎng)站營銷、網(wǎng)站制作、云服務(wù)器、App開發(fā)、品牌網(wǎng)站設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)