python裝飾器底層原理詳解
1 python裝飾器的作用
被裝飾對象加上裝飾器(戴了個帽子),被裝飾對象獲得了更強大的功能。
2 python裝飾器的原理
- python裝飾器本身是一個函數(shù)
- 這個函數(shù)的參數(shù)是一個函數(shù)對象
- 這個函數(shù)的返回值也是一個函數(shù)對象,這個函數(shù)的功能更強
- 大python裝飾器是python的一個語法糖(更簡便的語法)
3 python裝飾器的實現(xiàn)
3.1 最簡陋的裝飾器
# 自定義裝飾器
def super_(func):
def wrapper():
print('把內(nèi)褲穿到外面來,變身超人')
func()
print('會飛!')
return wrapper
@super_
def man():
print('會走')
# @super_原始語法結(jié)構(gòu)
# man = super_(man)
man()運行結(jié)果如下:

3.2 給有返回值的函數(shù)加上裝飾器
'''
給有返回值的函數(shù)加上裝飾器
'''
import time
def decorate(func):
def wrapper():
print('開始執(zhí)行時間:' + time.strftime('%Y-%m-%d %H:%M:%S'))
result = func()
print('結(jié)束執(zhí)行時間:' + time.strftime('%Y-%m-%d %H:%M:%S'))
return result
return wrapper
@decorate
def normal_func():
time.sleep(1)
print('normal_func執(zhí)行中......')
return 2 + 2
# @decorate原始語法結(jié)構(gòu)
# normal_func = decorate(normal_func)
print(normal_func())運行結(jié)果如下:

3.3 給有返回值和參數(shù)的函數(shù)加上裝飾器
'''
給有返回值和參數(shù)的函數(shù)加上裝飾器
'''
import time
def decorate(func):
def wrapper(*args, **kwargs):
print('開始執(zhí)行時間:' + time.strftime('%Y-%m-%d %H:%M:%S'))
result = func(*args, **kwargs)
print('結(jié)束執(zhí)行時間:' + time.strftime('%Y-%m-%d %H:%M:%S'))
return result
return wrapper
@decorate
def normal_func1(a, b):
time.sleep(1)
print('normal_func1執(zhí)行中......')
return a + b
@decorate
def normal_func2(a, b, c):
time.sleep(1)
print('normal_func2執(zhí)行中......')
return a + b + c
# @decorate原始語法結(jié)構(gòu)
# normal_func1 = decorate(normal_func1)
# normal_func2 = decorate(normal_func2)
print(normal_func1(1, 2))
print(normal_func2(1, 2, 3))運行結(jié)果如下:

可變參數(shù)原理:
1 定義時使用可變參數(shù):在函數(shù)定義時使用args,在函數(shù)調(diào)用時,所有未匹配到的位置參數(shù),會被放到args這個元組當(dāng)中。
在函數(shù)定義時使用**kwargs,在函數(shù)調(diào)用時,所有未匹配到的關(guān)鍵字參數(shù),會被放到kwargs這個字典當(dāng)中。
2 調(diào)用時使用可變參數(shù):在函數(shù)調(diào)用時使用args,是把args這個元組解包,元組內(nèi)的每個元素作為函數(shù)的位置參數(shù)傳遞。
在函數(shù)調(diào)用時使用**kwargs,是把kwargs這個字典解包,字典內(nèi)的每個元素作為函數(shù)的關(guān)鍵字參數(shù)傳遞。
def test1(a, b, c, d):
print(a+b+c+d)
print('傳統(tǒng)調(diào)用'.center(60, '='))
test1(1, 2, 3, 4) # 位置參數(shù)
test1(b=2, c=3, d=4, a=1) # 關(guān)鍵字參數(shù)
# 在函數(shù)定義時使用*args,在函數(shù)調(diào)用時,所有未匹配到的位置參數(shù),會被放到args這個元組當(dāng)中
# 在函數(shù)定義時使用**kwargs,在函數(shù)調(diào)用時,所有未匹配到的關(guān)鍵字參數(shù),會被放到kwargs這個字典當(dāng)中
def test2(*args, **kwargs):
print(args)
print(type(args))
print(kwargs)
print(type(kwargs))
print('定義時使用可變參數(shù)'.center(60, '='))
test2(1, 2, 3, 4, b=5, c=6)
# 在函數(shù)調(diào)用時使用*args,是把args這個元組解包,元組內(nèi)的每個元素作為函數(shù)的位置參數(shù)傳遞。
# 在函數(shù)調(diào)用時使用**kwargs,是把kwargs這個字典解包,字典內(nèi)的每個元素作為函數(shù)的關(guān)鍵字參數(shù)傳遞。
print('調(diào)用時使用可變參數(shù)'.center(60, '='))
test1(*(1, 2, 3, 4))
test1(**{'a':1, 'b':2, 'c':3, 'd':4})
test1(*(1, 2), **{'c':3, 'd':4})運行結(jié)果如下:

3.4 讓我還是那個我
'''
讓我還是那個我
'''
import time
from functools import wraps
def decorate(func):
@wraps(func) # 把wrapper的內(nèi)置屬性轉(zhuǎn)換成func的內(nèi)置屬性(name/doc)
def wrapper(*args, **kwargs):
print('開始執(zhí)行時間:' + time.strftime('%Y-%m-%d %H:%M:%S'))
result = func(*args, **kwargs)
print('結(jié)束執(zhí)行時間:' + time.strftime('%Y-%m-%d %H:%M:%S'))
return result
# wrapper.__name__ = func.__name__
# wrapper.__doc__ = func.__doc__
return wrapper
@decorate
def normal_func(a, b):
'''
這是一個測試函數(shù)
'''
time.sleep(1)
print('normal_func1執(zhí)行中......')
return a + b
print(normal_func.__name__)
print(normal_func.__doc__)
4 python裝飾器在自動化測試框架中的應(yīng)用
4.1 從一個需求開始
對自動化測試腳本需要增加日志打印功能:
- 測試用例執(zhí)行前打?。?/strong>測試用例【xxx】開始執(zhí)行
- 測試用例執(zhí)行完打?。?/strong>測試用例【xxx】執(zhí)行完畢
- 測試用例執(zhí)行完打印:測試用例【xxx】執(zhí)行耗時:xx秒
- 測試用例執(zhí)行完打印分割線
import time
from functools import wraps
def log_decorator(func):
@wraps(func) # 把wrapper的內(nèi)置屬性轉(zhuǎn)換成func的內(nèi)置屬性(name/doc)
def wrapper(*args, **kwargs):
print('測試用例[{}]開始執(zhí)行'.format(func.__name__))
time_start = time.time()
result = func(*args, **kwargs)
time_end = time.time()
print('測試用例[{}]執(zhí)行完畢'.format(func.__name__))
print('測試用例[{}]執(zhí)行耗時:%.2f秒'.format(func.__name__) % (time_end - time_start))
print('分割線'.center(60, '='))
return result
return wrapper到此這篇關(guān)于python裝飾器底層原理講解的文章就介紹到這了,更多相關(guān)python裝飾器底層原理講解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Jupyter notebook遠(yuǎn)程訪問服務(wù)器的方法
今天小編就為大家分享一篇Jupyter notebook遠(yuǎn)程訪問服務(wù)器的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05
python飛機大戰(zhàn) pygame游戲創(chuàng)建快速入門詳解
這篇文章主要介紹了python飛機大戰(zhàn) pygame游戲創(chuàng)建,結(jié)合實例形式詳細(xì)分析了Python使用pygame創(chuàng)建飛機大戰(zhàn)游戲的具體步驟與相關(guān)操作注意事項,需要的朋友可以參考下2019-12-12
python光學(xué)仿真實現(xiàn)光線追跡之空間關(guān)系
這篇文章主要介紹了python光學(xué)仿真中實現(xiàn)光線追跡的空間關(guān)系示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-10-10
python opencv 讀取本地視頻文件 修改ffmpeg的方法
今天小編就為大家分享一篇python opencv 讀取本地視頻文件 修改ffmpeg的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01

