一、函数装饰器示例
def report1(text,rs):
callnum = 0#定义一个变量,用于保存调用次数
def decorator(fuct):
#使用function.wraps装饰器,把相关的属性从fuct复制到inner中。
# 否则被装饰的函数调用__name__将打印的是inner
@wraps(fuct)
def inner(*args, **kwargs):
# 将callnum标记为自由变量,以便在内嵌函数中使用,否则会报错;
# 如果使用的外部变量是引用类型如list,则不需要声明,前提是非赋值操作。
nonlocal callnum
callnum += 1
try:
fuct(*args, **kwargs)#执行原来的函数,如果原函数有return,需要将原函数执行结果进行return
rs.append((text + str(callnum), fuct.__name__, 1, ''))#原函数未报错执行改语句,保存用例执行结果
except Exception as e:
rs.append((text + str(callnum), fuct.__name__, 0, str(e)[:100]))#保存原函数执行结果(捕获的异常)
raise #向外抛出异常
return inner #返回内部函数,取代被装饰的函数
return decorator #返回装饰器
@report('',[])#带参的装饰器必须以调用函数的形式进行,即名称后面加上()
def name():
print('--------------------')
二、类装饰器
class report:
def __init__(self,text,rs):
self.text = text
self.rs = rs
def __call__(self, fuct):#定义__call__函数,让类实例成为可调用对象
callnum = 0
@wraps(fuct)
def decorator(*args, **kwargs):
nonlocal callnum
callnum += 1
try:
fuct(*args, **kwargs)
self.rs.append((self.text + str(callnum), fuct.__name__, 1, ''))
except Exception as e:
self.rs.append((self.text + str(callnum), fuct.__name__, 0, str(e)[:100]))
raise
return decorator
网友评论