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获取GY-85九轴模块信息示例
Dec 05 Python
Python入门篇之数字
Oct 20 Python
win与linux系统中python requests 安装
Dec 04 Python
Python计算斗牛游戏概率算法实例分析
Sep 26 Python
Python断言assert的用法代码解析
Feb 03 Python
Python结合ImageMagick实现多张图片合并为一个pdf文件的方法
Apr 24 Python
详解利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击
Oct 09 Python
详解Python Matplot中文显示完美解决方案
Mar 07 Python
python 按钮点击关闭窗口的实现
Mar 04 Python
Python 串口通信的实现
Sep 29 Python
Django Form常用功能及代码示例
Oct 13 Python
用60行代码实现Python自动抢微信红包
Feb 04 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
是否存在第一台收音机的说法
2021/03/01 无线电
社区(php&&mysql)一
2006/10/09 PHP
PHP实现将浏览历史页面网址保存到cookie的方法
2015/01/26 PHP
几个javascript操作word的参考代码
2009/10/26 Javascript
jquery选择器(常用选择器说明)
2010/09/28 Javascript
JavaScript将Web页面内容导出到Word及Excel的方法
2015/02/13 Javascript
vue实现动态数据绑定
2017/04/28 Javascript
Vue封装一个简单轻量的上传文件组件的示例
2018/03/21 Javascript
15个顶级开源JavaScript框架和库
2018/10/10 Javascript
layui默认选中table的CheckBox复选框方法
2019/09/19 Javascript
全面解析JavaScript Module模式
2020/07/24 Javascript
Python中super关键字用法实例分析
2015/05/28 Python
python+Splinter实现12306抢票功能
2018/09/25 Python
深入理解Django自定义信号(signals)
2018/10/15 Python
Python3最长回文子串算法示例
2019/03/04 Python
python字符串分割及字符串的一些常规方法
2019/07/24 Python
基于pandas中expand的作用详解
2019/12/17 Python
python识别验证码图片实例详解
2020/02/17 Python
Python实现动态给类和对象添加属性和方法操作示例
2020/02/29 Python
python 将列表里的字典元素合并为一个字典实例
2020/09/01 Python
详解python的super()的作用和原理
2020/10/29 Python
python中re模块知识点总结
2021/01/17 Python
用HTML5制作烟火效果的教程
2015/05/12 HTML / CSS
AmazeUI 输入框组的示例代码
2020/08/14 HTML / CSS
美国专业汽车音响和移动电子产品零售商:Car Toys
2019/05/13 全球购物
美国购买舞会礼服网站:Couture Candy
2019/12/29 全球购物
阿迪达斯中国官网:Adidas中国
2020/12/14 全球购物
大队干部竞选演讲稿
2014/04/28 职场文书
爱岗敬业演讲稿
2014/05/05 职场文书
祖国在我心中演讲稿200字
2014/08/28 职场文书
见义勇为事迹材料
2014/12/24 职场文书
青年志愿者服务活动总结
2015/05/06 职场文书
第一节英语课开场白
2015/06/01 职场文书
趣味运动会加油词
2015/07/18 职场文书
深入理解redis中multi与pipeline
2021/06/02 Redis
python lambda 表达式形式分析
2022/04/03 Python