Python裝飾器的理解
阿新 • • 發佈:2019-01-29
Python裝飾器是什麼
Python裝飾器就是一個函式,它的產生是為了在不改變目標函式結構的基礎上為其增加功能,返回值是增加功能後的目標函式。
一個簡單的裝飾器 -為程式新增簡單的計時功能
import time
def get_run_time(method):
def wrapper():
start = time.time()
method()
end = time.time()
return end - start
return wrapper
@get_run_time
def helloworld ():
print('helloworld')
if __name__ == '__main__':
spend = helloworld()
print('spend time: {}'.format(spend))
執行結果:
...
helloworld
spend time: 1.50203704834e-05
目標函式帶引數的情況
當然有時候目標函式(在上面的程式中為helloworld
函式)是有引數的,下面做一些微小的改動
import time
def get_run_time(method):
def wrapper(*args, **kwargs) :
start = time.time()
method(*args, **kwargs)
end = time.time()
return end - start
return wrapper
@get_run_time
def helloworld(name):
print('I\'m {}, helloworld'.format(name))
if __name__ == '__main__':
spend = helloworld('wk')
print('spend time: {}' .format(spend))
執行結果:
...
I'm wk, helloworld
spend time: 2.09808349609e-05
裝飾器函式帶引數的情況
既然裝飾器是個函式,那它也是可以有引數的,此時只要將上述程式碼稍加改動即可
import time
def get_run_time(decimal):
def wrapper_of_wrapper(method):
def wrapper(*args, **kwargs):
start = time.time()
method(*args, **kwargs)
end = time.time()
return round(end - start, decimal)
return wrapper
return wrapper_of_wrapper
@get_run_time(decimal=16)
def helloworld(name):
print('I\'m {}, helloworld'.format(name))
if __name__ == '__main__':
spend = helloworld('wk')
print('spend time: {}'.format(spend))
# 下面這行先不用看,這是下一個標題的內容
print(helloworld.__name__)
增加了控制返回時間精度的功能,其實就是在原基礎上多封了一層,最外層是新增的一層,目的是增加一個相對全域性變數(能看懂就行了,能力有限,就不扯深的了),在上述程式碼中是decimal
執行結果:
...
I'm wk, helloworld
spend time: 4.60147857666e-05
wrapper
@functools.wraps
裝飾器返回的函式雖然結構與目標函式相似,但本質已經發生了變話,返回的是另一個函式,看上面程式中print(helloworld.__name__)
的輸出為wrapper
,再看看functools.wraps的效果
import time
import functools
def get_run_time(decimal):
def wrapper_of_wrapper(method):
@functools.wraps(method)
def wrapper(*args, **kwargs):
start = time.time()
method(*args, **kwargs)
end = time.time()
return round(end - start, decimal)
return wrapper
return wrapper_of_wrapper
@get_run_time(decimal=16)
def helloworld(name):
print('I\'m {}, helloworld'.format(name))
if __name__ == '__main__':
spend = helloworld('wk')
print('spend time: {}'.format(spend))
# 對比一下,只增加了@functools.wraps
print(helloworld.__name__)
執行結果:
...
I'm wk, helloworld
spend time: 2.09808349609e-05
helloworld