裝飾器

  經過使用閉包函數(嵌套函數),來達到不改變原方法,而對原方法添加功能的做用閉包

  

 1 import time
 2 from functools import wraps
 3 
 4 
 5 def timer(f):
 6     @wraps(f)
 7     def inner(*args,**kwargs):
 8         start = time.time()
 9         res = f(*args,**kwargs)
10         end = time.time()
11         print(end - start)
12         return res
13     return inner
14 
15 
16 @timer  #func = timer(func(a))
17 def func(a):
18     '''this is a function'''
19     return f'function:{a}'
20 
21 res = func('f')
22 print(res)
23 print(func.__name__)
24 print(func.__doc__)

  對func函數添加計算時間的功能,16行@語法,稱之爲語法糖,等同於 func = timer(func(a));app

  __name__ 和__doc__方法,可查看函數的方法和註釋,因爲使用了裝飾器,故顯示的都爲裝飾器中的屬性,若要顯示原來屬性,則使用functools的wrap方法對裝飾的函數進行裝飾;函數

  控制裝飾器的執行

  對裝飾器函數在外包一層函數,使用布爾值進行判斷調用this

 

 1 Flag = True
 2 def outer(Flag):
 3     def timer(f):
 4         @wraps(f)
 5         def inner(*args,**kwargs):
 6             if Flag:
 7                 start = time.time()
 8                 res = f(*args,**kwargs)
 9                 end = time.time()
10                 print(end - start)
11             else:
12                 res = f(*args,**kwargs)
13             return res
14         return inner
15     return timer
16 
17 @outer(Flag)
18 def func(a):
19     '''this is a function'''
20     return f'function:{a}'
21 
22 res = func('hello')
23 print(res)

經過修改布爾值,就可調控該裝飾器是否執行spa

  多個裝飾器

  當有多個裝飾器時,離函數最近的裝飾器先執行code

 1 def wrapper1(func):
 2     def inner():
 3         print('wrapper1 ,before func')
 4         func()
 5         print('wrapper1 ,after func')
 6     return inner
 7 
 8 def wrapper2(func):
 9     def inner():
10         print('wrapper2 ,before func')
11         func()
12         print('wrapper2 ,after func')
13     return inner
14 
15 @wrapper2
16 @wrapper1
17 def f():
18     print('in f')
19 
20 f()

  實際執行順序爲wrapper1,而後是wrapper2;在調用wrapper1時,返回的爲wrapper1的inner函數,此時對該inner函數,進行wrapper2的裝飾,故輸出以下圖。blog

        

  該輸出如,照鏡子,f爲鏡子,我稱之爲鏡子輸出io

相關文章
相關標籤/搜索