类外的装饰器方法装饰类方法,并调用该类的其他方法
场景:链接数据库的类,在执行数据库方面的操作时,经常会断开,此时需要调用该类的连接数据库方法来重新链接到数据库
class My_dbclient():
def __init__(self):
self.try_count=10
self.connect()
def connect(self):
print("数据库链接成功")
def insert(self):
# 可能会出现数据库断开链接的异常
print("正在执行保存操作")
for i in range(self.try_count):
try:
print("保存数据")
# raise NameError
return
except Exception:
time.sleep(1)
self.connect()
print(traceback.format_exc())
def select(self):
# 可能会出现数据库断开链接的异常
print("查询数据")
def delete(self):
# 可能会出现数据库断开链接的异常
print("删除数据")
就像insert方法中这样,可以捕获异常,并重新链接,然后再操作。
但是,无论增删改查,都需要这样来写,代码冗余。很自然,使用装饰器来解决。
示例:
常规的装饰器写法
def catch_error(fun):
def wrapper(*args, **kwargs):
for i in range(1, 10):
try:
fun(*args, **kwargs)
return
except Exception:
time.sleep(1)
print("链接错误---{}---次".format(i))
print("调用数据库链接方法,重新链接数据库")
print("信息保存失败")
return wrapper
@catch_error
def insert():
print("开始执行插入语句")
raise TimeoutError
现在我们想要装饰类方法,并在捕获数据库链接异常后,调用数据库链接方法重新链接。
解决办法:
在装饰器的内部函数 wrapper 的参数中,增加self参数
并在调用的函数fun中,增加self参数
如下,就可以使用self来调用connect这个方法了,同时,
def catch_error(fun):
def wrapper(self,*args, **kwargs):
for i in range(1, 10):
try:
fun(self,*args, **kwargs)
return
except Exception:
time.sleep(1)
print("链接错误---{}---次".format(i))
print("调用数据库链接方法,重新链接数据库")
self.connect()
print("信息保存失败")
return wrapper
完整代码:
import time
import traceback
def catch_error(fun):
def wrapper(self,*args, **kwargs):
for i in range(1, 10):
try:
fun(*args, **kwargs)
return
except Exception:
time.sleep(1)
print("链接错误---{}---次".format(i))
print("调用数据库链接方法,重新链接数据库")
self.connect()
print("信息保存失败")
return wrapper
@catch_error
def insert():
print("开始执行插入语句")
raise TimeoutError
class My_dbclient():
def __init__(self):
self.try_count = 10
self.connect()
def connect(self):
print("数据库链接成功")
@catch_error
def insert(self):
# 可能会出现数据库断开链接的异常
print("保存数据")
raise TimeoutError
def select(self):
# 可能会出现数据库断开链接的异常
print("查询数据")
def delete(self):
# 可能会出现数据库断开链接的异常
print("删除数据")
if __name__ == '__main__':
t = My_dbclient()
t.insert()