1.
importtime, datetimeclassly:def __init__(self, fun):
self.fun=funprint('this is the first step on' +str(datetime.datetime.now()))
time.sleep(1)
self.fun()def __call__(self):print('this is the thirty step on' +str(datetime.datetime.now()))
time.sleep(1)
@lydefshow():print('this is the second step on' +str(datetime.datetime.now()))
time.sleep(1)if __name__ == "__main__":
show()print('this is the fourth step on' + str(datetime.datetime.now()))
2.importtimeclassly(object):def __init__(self, fun):print("this is the first step")
time.sleep(1)
self.fun=fundef __call__(self, *args):print("this is the second step")
time.sleep(1)
self.fun(*args)print("this is the fourth step")
time.sleep(1)
@lydefshow(a1, a2, a3, a4):print('this is the thirty step', a1, a2, a3, a4)
time.sleep(1)
show("parm", "1", "1", "1")print("after first part call")
time.sleep(1)
show("parm", "2", "2", "2")print("after second part call")
從中可以發現:
(1).只要有被類裝飾器裝飾的物件,類裝飾器的 __init__ 函式就會執行(不需要呼叫)
(2).被類裝飾器裝飾的函式不論被呼叫幾次,__init__ 函式只會執行一次,並且它的執行是被裝飾函式宣告裝飾時就自動執行,不需要手動呼叫
(3).當被裝飾函式存在引數時,從 __call__ 函式傳進引數(不必須 *args,但這是一種規範 def __call__(self,*args,**kwargs))
*args是指字串,**kwargs是指字典
3.importtimeclassly:def __init__(self, one_parm, two_parm, three_parm):
self.one_parm=one_parm
self.two_parm=two_parm
self.three_parm=three_parmdef __call__(self, fun):print('性別為' + self.one_parm + "的" + self.two_parm + "歲的" +self.three_parm)
time.sleep(1)def info(*args):
fun(*args)returninfo
@ly("男", "22", "ly")defshow(name, age, ***):print('性別為' + *** + "的" + age + "歲的" +name)
show("藍月", "20", "男")
注意:(1).裝飾器有裝飾器的引數,函式(被裝飾器修飾的函式)有函式的引數,不可混淆
(2).裝飾器函式的引數從 __init__ 函式中傳,函式的引數從 __call__ 函式中傳
defdecorator_a(func):print 'get in decorator_a'
def inner_a(*args, **kwargs):print 'get in inner_a'
return func(*args, **kwargs)returninner_adefdecorator_b(func):print 'get in decorator_b'
def inner_b(*args, **kwargs):print 'get in inner_b'
return func(*args, **kwargs)returninner_b
@decorator_b
@decorator_adeff(x):print 'get in f'
return x * 2f(1)
執行如上所示**,最後的執行結果為:
get in decorator_a
get in decorator_b
get in inner_b
get in inner_a
get in f
我們來分析下,為什麼會是這樣的順序(驗證的過程中可以通過打斷點的方式來觀察函式的程式的執行流程)。
首先:1、裝飾器函式在被裝飾函式定義好後立即執行。
我們把**最後一行注掉:
# f(1)
重新執行,會發現最後執行結果為:
get in decorator_a
get in decorator_b
說明裝飾器函式在被裝飾函式定義好後就立即執行。而且執行順序是由下到上開始裝飾。呼叫decorator_a時,f被裝飾成inner_a,呼叫decorator_b時,f被裝飾成inner_b。
通過在最後執行:print(f), 執行結果為可驗證。
所以如上所示**中,最後執行f(1)時,f已經變成了inner_b,而inner_b中return的func,實則為inner_a, inner_a中return的func才是最終的f。
所以最後的呼叫順序為
inner_b --->inner_a--->f
執行結果為:
get in inner_b
get in inner_a
get in f
在實際應用的場景中,當我們採用上面的方式寫了兩個裝飾方法比如先驗證有沒有登入 @login_required , 再驗證許可權夠不夠時 @permision_allowed 時,我們採用下面的順序來裝飾函式:
@login_required
@permision_alloweddeff()#do something
return
總結一下:
多個裝飾器裝飾函式時,有個規律是從小到上包裹(裝飾)函式,從上到下執行。
原文:
python中 修飾器
參考文章 python中 修飾符 示例如下 def test func func test deffun print call fun 上面的 會輸出 call fun 修飾符有點像函式指標,python直譯器發現執行的時候如果碰到 修飾的函式,首先就解析它,找到它對應的函式進行呼叫,並且會把 修飾...
python 修飾器作用
在python的函式中,函式定義的上一行有 functionname的修飾,當直譯器讀到 這樣的修飾符之後,會先解析 後的內容,把 下一行的函式或者類作為 後邊的函式的引數,然後將返回值賦值給下一行修飾的函式物件。比如 a bdef c deffunca a print in func a deff...
python類中包含類 徹底搞懂Python中的類
python類的定義 python 中定義乙個類使用 class 關鍵字實現,其基本語法格式如下 class 類名 多個 0 類屬性.多個 0 類方法.注意,無論是類屬性還是類方法,對於類來說,它們都不是必需的,可以有也可以沒有。另外,python 類中屬性和方法所在的位置是任 意的,即它們之間並沒...