Python - 采用 contextmanage 简化代码
contextlib.contextmanage
Python 2.7 documents:
https://docs.python.org/2.7/library/contextlib.html?highlight=contextmanage#contextlib.contextmanager
场景:flask_sqlalchemy :数据库的自动提交和回滚
如果频繁的修改数据库中的数据,每次使用 try/except、rollback()、raise e 会比较繁琐,可采用 contextlib.contextmanage 进行简化
- 简化前采用 try/except :
try:
user_db = User(email=self.email, nickname=self.nickname,password=self.password)
db.session.add(user_db)
db.session.commit()
except Exception as e:
db.session.rollback()
raise e
- 采用 contextmanager 简化后
from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy
from contextlib import contextmanager
class SQLAlchemy(_SQLAlchemy):
@contextmanager
def auto_commit(self):
try:
yield
self.session.commit()
except Exception as e:
self.session.rollback()
raise e
db = SQLAlchemy()
- 可利用 with 上下文管理方法调用:
with db.auto_commit():
user_db = User(email=self.email, nickname=self.nickname,password=self.password)
db.session.add(user_db)
被装饰器装饰的函数被分为三部分:
- with 语句中的代码块执行前,执行函数中 yield 之前的代码
- yield 返回的内容赋值给 as 之后的变量
- with 代码块执行完毕后,执行函数中 yield 之后的代码
[参考文献]
- flask-SQLAlchemy数据库模型插入数据的时候使用session.commit()必须处理异常回滚db.session.rollback() https://blog.csdn.net/weixin_43343144/article/details/87106213
- contextmanager: 上下文管理器类和上下文管理器装饰器 https://blog.csdn.net/weixin_42359464/article/details/80742387#three