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)

被装饰器装饰的函数被分为三部分:

  1. with 语句中的代码块执行前,执行函数中 yield 之前的代码
  2. yield 返回的内容赋值给 as 之后的变量
  3. with 代码块执行完毕后,执行函数中 yield 之后的代码

[参考文献]

  1. flask-SQLAlchemy数据库模型插入数据的时候使用session.commit()必须处理异常回滚db.session.rollback() https://blog.csdn.net/weixin_43343144/article/details/87106213
  2. contextmanager: 上下文管理器类和上下文管理器装饰器 https://blog.csdn.net/weixin_42359464/article/details/80742387#three
posted @ 2019-06-16 17:43  SXISZERO  阅读(447)  评论(0编辑  收藏  举报