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基础教程之循环介绍
Aug 29 Python
python统计一个文本中重复行数的方法
Nov 19 Python
Python和perl实现批量对目录下电子书文件重命名的代码分享
Nov 21 Python
python+pillow绘制矩阵盖尔圆简单实例
Jan 16 Python
浅谈python配置与使用OpenCV踩的一些坑
Apr 02 Python
idea创建springMVC框架和配置小文件的教程图解
Sep 18 Python
Python 单元测试(unittest)的使用小结
Nov 14 Python
python 读取竖线分隔符的文本方法
Dec 20 Python
python微信撤回监测代码
Apr 29 Python
使用python3批量下载rbsp数据的示例代码
Dec 20 Python
Python对象的属性访问过程详解
Mar 05 Python
Python3标准库之threading进程中管理并发操作方法
Mar 30 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中动态HTML的输出技术
2006/10/09 PHP
一个简单的PHP投票程序源码
2007/03/11 PHP
php使用curl通过代理获取数据的实现方法
2016/05/16 PHP
PHP实现的折半查询算法示例
2017/10/09 PHP
php微信开发之谷歌测距
2018/06/14 PHP
取选中的radio的值
2010/01/11 Javascript
网页上的Javascript编辑器和代码格式化
2010/04/25 Javascript
javascript制作的滑动图片菜单
2015/05/15 Javascript
JS实现网页每隔3秒弹出一次对话框的方法
2015/11/09 Javascript
JS简单实现String转Date的方法
2016/03/02 Javascript
vue如何获取点击事件源的方法
2017/08/10 Javascript
vue写一个组件
2018/04/09 Javascript
JQuery特殊效果和链式调用操作示例
2019/05/13 jQuery
微信小程序非跳转式组件授权登录的方法示例
2019/05/22 Javascript
vue input输入框关键字筛选检索列表数据展示
2020/10/26 Javascript
七行JSON代码把你的网站变成移动应用过程详解
2019/07/09 Javascript
微信小程序的开发范式BeautyWe.js入门详解
2019/07/10 Javascript
为nuxt项目写一个面包屑cli工具实现自动生成页面与面包屑配置
2019/09/29 Javascript
TypeScript 运行时类型检查补充工具
2020/09/28 Javascript
python实现中文输出的两种方法
2015/05/09 Python
简单解决Python文件中文编码问题
2015/11/22 Python
Linux中安装Python的交互式解释器IPython的教程
2016/06/13 Python
Python基于sftp及rsa密匙实现远程拷贝文件的方法
2016/09/21 Python
Python常见字符串操作函数小结【split()、join()、strip()】
2018/02/02 Python
tensorflow 获取模型所有参数总和数量的方法
2018/06/14 Python
Selenium定时刷新网页的实现代码
2018/10/31 Python
python实现将列表中各个值快速赋值给多个变量
2020/04/02 Python
python爬虫破解字体加密案例详解
2021/03/02 Python
html5的canvas实现3d雪花飘舞效果
2013/12/27 HTML / CSS
飞利浦法国官网:Philips法国
2019/07/10 全球购物
什么是反射?如何实现反射?
2016/07/25 面试题
公司担保书格式范文
2014/05/12 职场文书
未中标通知书
2015/04/17 职场文书
导游词之山西-五老峰
2019/10/07 职场文书
2019年中学生的思想品德评语集锦
2019/12/19 职场文书
浅谈spring boot使用thymeleaf版本的问题
2021/08/04 Java/Android