本文實例講述了Python裝飾器原理與基本用法。分享給大家供大家參考,具體如下:
裝飾器:
意義:在不能改變原函數的源代碼,和在不改變整個項目中原函數的調用方式的情況下,給函數添加新的功能
由于不允許改變函數的源代碼,在忽略調用方式的情況下,我們可能會有以下結果:
1
2
3
4
5
6
7
8
9
|
def decorator(func): func() print ( "logging" ) def test1(): print ( "test1" ) def test2(): print ( "Test2" ) decorator(test1) decorator(test2) |
但這改變了原本的調用方式,原本是test1(),現在是decorator(test1)
那么如果我們為了使調用方式不變,是否可以使裝飾好的函數decorator的返回值是一個我們需要的函數,再賦值給原來的函數名呢?
于是:
1
2
3
4
5
6
7
8
|
def timmer1(func): def warpper(): start_time = time.time() func() stop_time = time.time() print ( "the func run time is %s" % (stop_time - start_time)) return warpper test3 = timmer1(test3) |
好像上面這段代碼并沒有改變原來的調用方式,調用原來的test3,相當于運行timmer1中的warpper
如果對于無參數的函數來說,上面的代碼已經實現了我們的目的,但對于帶參數的函數,上面的代碼沒有傳入參數,所以仍然需要修改
于是:
1
2
3
4
5
6
7
|
def timmer2(func): def warpper( * args, * * kwargs): start_time = time.time() func( * args, * * kwargs) stop_time = time.time() print ( "the func run time is %s" % (stop_time - start_time)) return warpper |
在上上面的代碼中,由于實質上,test3已經等于wrapper,所以可以直接使用,test3(參數)來傳入參數,為了處理參數不確定數量問題,可以使用可變長度參數
上面代碼還存在一個問題,無法獲取原本函數中的返回值,那么我們還需要加上一些東西:
1
2
3
4
5
6
7
8
9
|
import time def timmer2(func): def warpper( * args, * * kwargs): start_time = time.time() res = func( * args, * * kwargs) return res stop_time = time.time() print ( "the func run time is %s" % (stop_time - start_time)) return warpper |
使用一個變量記錄下原函數的返回值。
這樣我們就實現了裝飾器的基本功能。
補充:
python提供了一個功能:
1
2
3
4
|
@裝飾器名 def 目標裝飾函數名(): pass #上面的效果是 目標裝飾函數名=裝飾器(目標裝飾函數名) |
所以在需要替換原函數的時候,可以在目標裝飾函數定義的上一行加上@裝飾器名
所以上面的代碼會變成:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
def timmer2(func): def warpper( * args, * * kwargs): start_time = time.time() func( * args, * * kwargs) stop_time = time.time() print ( "the func run time is %s" % (stop_time - start_time)) return warpper @timmer2 def test7(): print ( "test7" ) @timmer2 def test6(x): print (x) test7() test6( 2 ) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import time def timmer2(func): def warpper( * args, * * kwargs): start_time = time.time() res = func( * args, * * kwargs) return res stop_time = time.time() print ( "the func run time is %s" % (stop_time - start_time)) return warpper @timmer2 def test4(): print ( "test4 run" ) return "test4 done" test4() print ( "--------" ) print (test4()) |
第二個補充:
可以一個函數,可以使用多個裝飾器
比如:
@裝飾器1
@裝飾器2
希望本文所述對大家Python程序設計有所幫助。
原文鏈接:https://www.cnblogs.com/progor/p/8410776.html