关于一个yield和with的问题

关于一个yield和with的问题

from flask_sqlalchemy import SQLAlchemy as BaseSQLAlchemy

from contextlib import contextmanager

#自定义一个SQLAlchemy继承flask_sqlalchemy的,方便自定义方法!!!

class SQLAlchemy(BaseSQLAlchemy):

#利用contextmanager管理器,对try/except语句封装,使用的时候必须和with结合!!!

@contextmanager

def auto_commit_db(self):

try:

yield # <---这里这个yield怎么理解?

self.session.commit()

except Exception as e:

# 加入数据库commit提交失败,必须回滚!!!

self.session.rollback()

raise e

db = SQLAlchemy()

添加数据的时候需要用到with:

with db.auto_commit_db():

user_db = User(nickname=self.nickname, password=self.password)

db.session.add(user_db)


回答:

建议深入理解生成器后研究下contextlib的代码,下面简单解释下contextmanager怎么把被修饰对象的 try ... finally ... 分配到with约定的 __enter__, __exit__方法中的。

contextmanager的使用方式,可见他要求装饰对象是一个生成器

    Typical usage:

@contextmanager

def some_generator(<arguments>):

<setup>

try:

yield <value>

finally:

<cleanup>

此处yield的作用就是协程切换,如果yield后有值,还可以传出(with 子句 as 后)。
contextmanager 在 __enter__ 中第一次调用 next(gen),代码执行到auto_commit_dbyield处转出,执行 with 子句的代码

user_db = User(nickname=self.nickname, password=self.password)

db.session.add(user_db)

contextmanager 在 __exit__ 中第二次调用 next(gen),也就就是with子句结束前执行auto_commit_db的其余部分,完成资源管理的其他任务。


回答:

等待 self.session.commit()执行返回

以上是 关于一个yield和with的问题 的全部内容, 来源链接: utcz.com/p/937677.html

回到顶部