装饰器:
装饰器是高阶函数,但装饰器是对传入函数的功能的装饰(功能增强)
使用非侵入式代码,对原有代码(函数)进行功能上的增强,装饰器的本质就是一个函数,这个函数会包装被包装函数,包装函数增强代码不会干扰被包装函数的业务执行。
作用:不影响原有函数的功能,还能添加新的功能
如:增加打印日志的功能等
装饰器语法糖,使用方式:@
基于闭包
基础语法: @logger
def logger(fn):
def wrapper(*args,**kwargs): #包装函数
print('begin')
x = fn(*args,**kwargs)
print('end')
return x
return wrapper
@logger # 装饰器函数 等价于add = logger(add)
def add(x,y): #被包装函数
return x + y
print(add(45,40))
无参装饰器
#无参装饰器
def func1(func): #外部闭包函数的参数是func,func是被装饰的函数对象
def func2():
print("aaabbb")
return func() #返回了外部函数接收的参数,被装饰函数的调用
return func2
@func1 #func1(func)()
def func():
print("结束")
func()
#func被装饰, @func1 func相当于func1(func); func()相当于func1(func)()
接收被装饰的函数作为参数,而且还要继续调用一次 [return func()]
注意:
#return func 返回了集装箱,返回了函数对象,函数名
#return func() 返回的是函数调用,真正意义上返回的是func()执行之后的结果
带参装饰器
1.它是一个函数
2.函数作为它的形参
3.返回值是一个不带参的装饰器函数
4. 使用@functionname(参数列表)方式调用
5.可以看做在装饰器外层又加了一层函数
装饰器函数带参:@func1(cs = “name”)(func)()
多一层包装来接收装饰器的参数–最外层接收装饰器的参数
被装饰函数作为参数–第二层接收
举例:
#装饰器函数带参
def arg_func(sex):
def func1(b_func):
def func2():
if sex == "man":
print("你是男生")
if sex == "woman":
print("你是女生")
return b_func()
return func2
return func1
@arg_func(sex="man") #arg_func(sex="man")(man)() 参数在最外层函数传入,然后传入被装饰函数
def man():
print("好好上班")
@arg_func(sex="woman")
def woman():
print("好好上班+1")
man()
woman()
被装饰函数带参:(用的比较多)
需要在最内部函数传入参数
被装饰函数作为参数–最外层函数接收
被装饰函数调用时需要传参
举例:
def func1(func):
def func2(x, y):
print(x, y)
x += 5
y += 5
return func(x,y) #需要传参数
return func2
@func1 #func1(mysum)()
def mysum(a,b):
print(a + b)
# return a+b
mysum(1,2)
举例2:
#装饰器语法糖
def logger(fn):
def _logger(*args,**kwargs): #包装函数 收集函数
print("before")
ret = fn(*args,**kwargs) #调用函数add1 #参数解构:args返回元组,需要解构;字典也需要解构;闭包
print("end")
return ret
return _logger
@logger #等价于add1 = logger(add1)()--即把下面的标识符add1作为一个参数传入
def add1(x,y,*,z=6): #内存中指向包装函数 相当于内层函数:内层函数_logger(返回谁,add1相当于谁,如:返回_logger,相当于_logger;返回1,add1相当于1)
return x+y+z
# t= logger(add1) #内层函数_logger
# r=t(4,5,z=9)
r = add1(4,5,z=20)
print(r)
其他常用装饰器:
allure的标记装饰器:
@allure.feature:功能点的描述,可以理解成模块,相当于class级的标签
@allure.story:故事,可以理解为场景,相当于method级的标签
pytest常用装饰器:
@pytest.mark.parametrize(‘参数名’,list)可以实现测试用例参数化
@pytest.mark.run(order=x) 改变用例执行顺序
@pytest.fixture() 可将被fixture标记的函数当作参数使用
@pytest.mark.skip(用于函数外,跳过测试用例)
…
17万+

被折叠的 条评论
为什么被折叠?



