python的上下文管理
2024-09-01 17:54:18
说道上下文管理首先想到的就是这个:
class MyResource:
def __enter__(self):
print("查询开始")
return self def __exit__(self, exc_type, exc_val, exc_tb):
print("查询结束") def query(self):
print("查询中") with MyResource() as f:
f.query()
执行结果
查询开始
查询中
查询结束
但是我们这里要说的不是这个,
from contextlib import contextmanager class MyResource:
def query(self):
print("查询中") @contextmanager
def make_myresource():
print("查询开始")
yield MyResource()
print("查询结束") # 这里的f是yield后面返回的实例
with make_myresource() as f:
f.query()
python给了我们一个contextmanager,contextmanager最大的好处就是可以将不是上下文处理器的类变成一个类似上下文处理的方式来解决问题。
上面的运行结果依然是:
查询开始
查询中
查询结束
简单的例子,我想把我一本图书的名字加上书名号输出:
from contextlib import contextmanager @contextmanager
def make_myresource():
print("《", end='')
yield
print("》") # 这里的f是yield后面返回的实例
with make_myresource():
print("my world", end='')
《my world》
下面看一个例子:
try:
# 此时已经支持事务,commit之前都没有真正提交
gift = Gift()
gift.isbn = isbn
# current_user是实例化后的user模型
gift.uid = current_user.id
current_user.beans += 0.5
db.session.add(gift)
db.session.commit()
except Exception as e:
db.session.rollback()
raise e
这个例子是sqlalchemy操作里时常要使用到的事务回滚的代码,为了防止本次写入失败对下一次写入的影响,我们时常需要捕捉到异常并回滚到初始状态。这样的异常捕获代码会多次出现在我们的项目里面,所以我们考虑修改他,如何让代码简化,这时候应当使用contextmanager来解决这个问题。
from contextlib import contextmanager from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy
from sqlalchemy import Column, SmallInteger class SQLAlchemy(_SQLAlchemy):
@contextmanager
def auto_commit(self):
try:
yield
self.session.commit()
except Exception as e:
self.session.rollback()
raise e db = SQLAlchemy()
@web.route('/gifts/book/<isbn>')
@login_required
def save_to_gifts(isbn):
if current_user.can_save_to_list():
with db.auto_commit():
# 此时已经支持事务,commit之前都没有真正提交
gift = Gift()
gift.isbn = isbn
# current_user是实例化后的user模型
gift.uid = current_user.id
current_user.beans += 0.5
db.session.add(gift)
最新文章
- Tips for newbie to read source code
- 【强烈推荐】数据库迁移利器:Migrator.Net
- asp.net网站运行出错:the underlying provider failed on open的解决
- A+B for Matrices 及 C++ transform的用法
- SQL语言笔记
- pragram once
- uva 10125 - Sumsets
- EffectiveC#16--垃圾最小化
- 第48篇 字符编码探密--ASCII,UTF8,GBK,Unicode
- JAVA 继承基本类、抽象类、接口
- 011_python常用查询
- JavaScript中的各种宽高总结
- 给div";上";滑动条
- day7 字符集转换
- SQL*Plus连接符拼接输出
- ML(附录4)——拉格朗日乘数法
- c语言数字图像处理(三):仿射变换
- JavaEE-案例1-网站信息展示
- Innosetup的状态页面和向导页面解释
- C#中正则表达式编程(未完,待补充)
热门文章
- web前端的环境配置
- 安装ANSYS19.0的正确方法(附下载)
- HUD:3746-Cyclic Nacklace(补齐循环节)
- Benelux Algorithm Programming Contest 2014 Final
- Mdrill集群安装
- 1022: [SHOI2008]小约翰的游戏John9(Auti_SG)
- git---gui使用
- Redis实现之复制(一)
- 【SDOI2009】HH的项链 线段树
- [oldboy-django][2深入django]Form组件功能: 数据格式验证 + 保留上次输入的值