Python上下文管理器全实例详解


Posted in Python onNovember 12, 2019

Python上下文管理器

简介

最近用到这个,仔细了解了一下,感觉是十分有用的,记录一下

使用场景

当我们需要获取一个临时打开的资源,并在使用完毕后进行资源释放和异常处理,利用try-catch语句可以完成,举个例子。

打开文件:

f = None
try:
 print("try")
 f = open("__init__.py", "r")
 print(f.read())
except Exception as e:
 print("exception")
finally:
 if f:
  print("finally")
  f.close()

利用上下文管理器:

class OpenHandle:

 def __init__(self, filename, mode):
  self.filename = filename
  self.mode = mode

 def __enter__(self):
  self.f = open(self.filename, self.mode)
  return self.f

 def __exit__(self, exc_type, exc_val, exc_tb):
  if exc_type:
   print("exception")
  else:
   print("normal")
  self.f.close()

with OpenHandle("book.txt", "r") as f:
 print(f.read())

这样可以利用with-as语句改写代码,让程序员关注业务主流程,去掉对于资源的获取和关闭这些重复操作。提升代码的可读性。好处很大。

执行顺序

执行顺序是理解这种写法的关键:

  • 初始化,执行handle的__init__()
  • __enter__()方法,获取资源对象,返回给as后的变量
  • 业务代码逻辑
  • __exit__方法,传入3个参数,异常类型,异常对象,调用栈对象,无异常都为None
  • 抛出异常或者正常结束

函数式上下文管理器

利用from contextlib import contextmanager这个装饰器可以将函数装饰为上下文管理器,其实这个装饰背后也是返回一个实现了__enter__和__exit__方法的类

from contextlib import contextmanager

@contextmanager
def managed_resource(*args, **kwds):
 # Code to acquire resource, e.g.:
 resource = acquire_resource(*args, **kwds)
 try:
  yield resource
 finally:
  # Code to release resource, e.g.:
  release_resource(resource)

>>> with managed_resource(timeout=3600) as resource:
...  # Resource is released at the end of this block,
...  # even if code in the block raises an exception

模板代码

sqlalchemy会话上下文管理器

利用这个管理sqlalchemy会话对象的获取和释放,控制事务是再合适不过了

class DbTransaction:

 def __init__(self, session_maker):
  self.session_maker = session_maker

 def __enter__(self):
  self.session = self.session_maker()
  return self.session

 def __exit__(self, exc_type, exc_val, exc_tb):
  if exc_type:
   self.session.rollback()
  else:
   self.session.commit()
  self.session.close()
  return False if exc_type else True

以上就是全部相关知识点,感谢大家的学习和对三水点靠木的支持。

Python 相关文章推荐
Python 用户登录验证的小例子
Mar 06 Python
wxPython实现窗口用图片做背景
Apr 25 Python
实例讲解Python爬取网页数据
Jul 08 Python
Python全局变量与局部变量区别及用法分析
Sep 03 Python
Python3爬虫学习之MySQL数据库存储爬取的信息详解
Dec 12 Python
PyQt4 treewidget 选择改变颜色,并设置可编辑的方法
Jun 17 Python
python多进程下实现日志记录按时间分割
Jul 22 Python
详解Python中正则匹配TAB及空格的小技巧
Jul 26 Python
python字典的值可以修改吗
Jun 29 Python
Python Charles抓包配置实现流程图解
Sep 29 Python
python实现在列表中查找某个元素的下标示例
Nov 16 Python
Python实现Appium端口检测与释放的实现
Dec 31 Python
python3-flask-3将信息写入日志的实操方法
Nov 12 #Python
Python API自动化框架总结
Nov 12 #Python
python的scipy实现插值的示例代码
Nov 12 #Python
python对验证码降噪的实现示例代码
Nov 12 #Python
Python FTP文件定时自动下载实现过程解析
Nov 12 #Python
详解在python操作数据库中游标的使用方法
Nov 12 #Python
如何分离django中的媒体、静态文件和网页
Nov 12 #Python
You might like
PHP常用代码大全(新手入门必备)
2010/06/29 PHP
Laravel路由设定和子路由设定实例分析
2016/03/30 PHP
PHP pear安装配置教程
2016/05/14 PHP
php获取数据库结果集方法(推荐)
2017/06/01 PHP
阿里云PHP SMS短信服务验证码发送方法
2017/07/11 PHP
FireFox与IE 下js兼容触发click事件的代码
2008/11/20 Javascript
IE6 弹出Iframe层中的文本框“经常”无法获得输入焦点
2009/12/27 Javascript
JavaScript CSS 修改学习第四章 透明度设置
2010/02/19 Javascript
JQuery上传插件Uploadify使用详解及错误处理
2010/04/27 Javascript
定义JavaScript二维数组采用定义数组的数组来实现
2012/12/09 Javascript
js弹出div并显示遮罩层
2014/02/12 Javascript
浅谈利用JavaScript进行的DDoS攻击原理与防御
2015/06/04 Javascript
JavaScript实现可拖拽的拖动层Div实例
2015/08/05 Javascript
jquery实现ajax加载超时提示的方法
2016/07/23 Javascript
js微信分享API
2020/10/11 Javascript
Jquery Easyui进度条组件Progress使用详解(8)
2020/03/26 Javascript
JavaScript实现的冒泡排序法及统计相邻数交换次数示例
2017/04/26 Javascript
bootstrap daterangepicker汉化以及扩展功能
2017/06/15 Javascript
基于Vue实现可以拖拽的树形表格实例详解
2018/10/18 Javascript
JavaScript中构造函数与原型链之间的关系详解
2019/02/25 Javascript
NodeJS 文件夹拷贝以及删除功能
2019/09/03 NodeJs
详解微信小程序之提高应用速度小技巧
2020/01/07 Javascript
Python中使用strip()方法删除字符串中空格的教程
2015/05/20 Python
详解js文件通过python访问数据库方法
2019/03/03 Python
Pycharm连接远程服务器并实现远程调试的实现
2019/08/02 Python
Django上线部署之IIS的配置方法
2019/08/22 Python
用Python写一个自动木马程序
2019/09/17 Python
Selenium常见异常解析及解决方案示范
2020/04/10 Python
英国时尚服饰电商:Boohoo
2017/10/12 全球购物
结婚邀请函范文
2014/01/14 职场文书
难忘的一天教学反思
2014/04/30 职场文书
大学自主招生推荐信
2014/05/10 职场文书
三八节祝酒词
2015/08/11 职场文书
会议主持词通用版
2019/04/02 职场文书
Vue鼠标滚轮滚动切换路由效果的实现方法
2021/08/04 Vue.js
浅谈Redis缓冲区机制
2022/06/05 Redis