一、什么是装饰器以及装饰器的分类
装饰器:装饰函数或者类
二、装饰器分类
两种:
函数装饰器
类装饰器
三、装饰器的定义及应用
装饰器怎么去定义,实现作用
数据驱动 ddt @data @unpack
demo.py
'''
装饰器:函数的扩展功能,装饰函数及类
装饰器的作用:扩展函数的功能,增强函数或者类的功能 标识符@
函数特征:函数可以作为参数
'''
# 统计方法运行耗时多久 业务Hi+统计时间
import time
def runtime(func):
def wrapper(*args, **kwargs):
print("2、welcome Tencent")
start = time.time()
# 实现原来的业务
func()
time.sleep(2)
end = time.time()
cost = end-start
print(f"3、耗时:{cost}")
return wrapper
@runtime
def Hi():
"""函数体"""
print("1、welcome")
Hi()
输出
2、welcome Tencent
1、welcome
3、耗时:2.0004632472991943
四、装饰器的实现原理
'''
装饰器:函数的扩展功能,装饰函数及类
装饰器的作用:扩展函数的功能,增强函数或者类的功能 标识符@
函数特征:
1、可以作为参数
2、函数可以返回函数
'''
# 统计方法运行耗时多久 业务Hi+统计时间
import time
def runtime(func): # 这里把函数作为参数
def wrapper(*args, **kwargs):
print("2、welcome Tencent")
start = time.time()
# 实现原来的业务
func() # 调用Hi()函数
time.sleep(2)
end = time.time()
cost = end-start
print(f"3、耗时:{cost}")
return wrapper # 返回函数
@runtime
def Hi():
"""函数体"""
print("1、welcome one")
def Hi_vip():
print("4、welcom two")
# Hi()
# 被装饰方法+@runtime = <Hi_vip = runtime(Hi_vip)>
Hi_vip11 = runtime(Hi_vip) # 返回的wrapper函数
Hi_vip11()
输出
2、welcome Tencent
4、welcom two
3、耗时:2.000028371810913
引申Hi_vip11的函数调用
# 被装饰方法+@runtime = <Hi_vip = runtime(Hi_vip)>
Hi_vip1 = runtime(Hi_vip) # 返回的wrapper函数 给装饰方法起了别名,这个别名就是原来的方法名↓↓↓
# 右边传入Hi_vip 返回wrapper函数,又给这个函数新起一个名Hi_vip1,调用这个函数即可,也就是调用了传参后的wrapper函数
def wrapper(*args, **kwargs):
print("2、welcome Tencent")
start = time.time()
# 实现原来的业务
Hi_vip() # 调用Hi()函数
time.sleep(2)
end = time.time()
cost = end - start
print(f"3、耗时:{cost}")
Hi_vip1()
多参数传入函数
def runtime(func): # 这里把函数作为参数
def wrapper(*args, **kwargs):
print("2、welcome Tencent")
start = time.time()
# 实现原来的业务
func(*args, **kwargs) # 调用Hi()函数
time.sleep(2)
end = time.time()
cost = end-start
print(f"3、方法名:{func.__name__} 耗时:{cost} 参数{args}")
return wrapper # 返回函数
@runtime
def Hi():
"""函数体"""
print("1、welcome one")
def Hi_vip():
print("4、welcom two")
@runtime
def sum(x, y):
sum = x+y
print(sum)
sum(2, 3)
输出
2、welcome Tencent
5
3、方法名:sum 耗时:2.0010457038879395 参数(2, 3)
五、装饰器在自动化测试框架中的实战应用
数据驱动 ddt pytest allure …
独立搭建框架:装饰器
业务层次:日志输出等。。
逻辑层次:授权
装饰器实现日志的输出
# 统计方法运行耗时多久 业务Hi+统计时间+日志输出
import time
import logging
logger = logging.getLogger(__name__)
def runtime(func): # 这里把函数作为参数
def wrapper(*args, **kwargs):
try:
print("2、welcome Tencent")
start = time.time()
# 实现原来的业务
func(*args, **kwargs) # 调用Hi()函数
time.sleep(2)
end = time.time()
cost = end-start
print(f"3、方法名:{func.__name__} 耗时:{cost} 参数{args}")
except Exception as error:
# 错误日志的输出
logger.error(f"方法名:{func.__name__}有报错,\n报错详细信息:"+str(error))
finally:
# 统计耗时,日志输出
logger.info(f"方法名:{func.__name__} 耗时:{cost} 参数{args}")
return wrapper # 返回函数
@runtime
def sum(x, y):
sum = x+y
print(sum)
if __name__ == "__main__":
# logging几大组件:日志器:日志输出的入口(必须) 处理器:决定当前日志在什么地方书法 日志格式(有默认) 过滤器
logger.setLevel(logging.DEBUG) # 指定日志级别
# 处理器
sh = logging.StreamHandler() # 控制台处理器
logger.addHandler(sh) # 日志器
sum(2, 1, 3) # sum(2, 3)
输出
2、welcome Tencent
5
3、方法名:sum 耗时:2.0000298023223877 参数(2, 3)
方法名:sum 耗时:2.0000298023223877 参数(2, 3)
error
D:\anaconda\python.exe C:/Users/bairong/Desktop/0509show/demo.py
2、welcome Tencent
方法名:sum有报错,
报错详细信息:sum() takes 2 positional arguments but 3 were given
Traceback (most recent call last):
File "C:/Users/bairong/Desktop/0509show/demo.py", line 72, in <module>
sum(2 ,1 ,3)
File "C:/Users/bairong/Desktop/0509show/demo.py", line 32, in wrapper
logger.info(f"方法名:{func.__name__} 耗时:{cost} 参数{args}")
UnboundLocalError: local variable 'cost' referenced before assignment