需求场景
在执行完对资源的操作后再执行一些动作,若此动作执行失败,需要对之前对资源的操作进行回退。
示例
在执行完do_something_to_db 函数后,需要执行after_do_db 函数,但是当after_do_db 函数执行错误,需要对do_something_to_db 函数之前所做的操作进行清理、回退
这时使用with语句可以比较方便的进行回退操作,相对于不加with的语句显得优雅许多不用每次调用after_do_db时都加try...except...回退清理代码
代码
class BaseException(Exception):
message = "This is the base Exception"
def __init__(self, **kw):
self.msg = self.message % kw
def __str__(self):
return self.msg
class MyExcep(BaseException):
message = ("error is: %(name)s, reason is %(reason)s")
def do_db(param1, param2):
print("do db")
print(param1, param2)
return 123
def un_do_db(param1, param2):
print("undo db")
def after_do_db(r):
print(r)
# return True
raise Exception("Error")
@contextlib.contextmanager
def do_something_to_db(param1, param2):
res = do_db(param1, param2)
try:
yield res
except Exception:
un_do_db(param1, param2)
raise MyExcep(name="Error", reason="the db action is Error")
使用
# 使用with版本
with do_something_to_db('123', '345') as r:
after_do_db(r)
# 不使用with版本
param1 = '123'
param2 = '345'
res = do_something_to_db(param1 , param2)
try:
after_do_db(res)
except Exception as e:
un_do_db(param1, param2)

博客围绕Python展开,介绍了一种需求场景,即在对资源操作后执行其他动作,若该动作失败,需对之前资源操作回退。还给出示例,说明使用特定语句进行回退操作更优雅,无需每次调用都添加回退清理代码。
172万+

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



