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多线程编程(五):死锁的形成
Apr 05 Python
Python3读取UTF-8文件及统计文件行数的方法
May 22 Python
Python实现识别手写数字 简易图片存储管理系统
Jan 29 Python
Python遍历numpy数组的实例
Apr 04 Python
基于python OpenCV实现动态人脸检测
May 25 Python
基于windows下pip安装python模块时报错总结
Jun 12 Python
django创建最简单HTML页面跳转方法
Aug 16 Python
Python数据可视化:箱线图多种库画法
Nov 06 Python
wxPython电子表格功能wx.grid实例教程
Nov 19 Python
如何写python的配置文件
Jun 07 Python
python 判断一组数据是否符合正态分布
Sep 23 Python
微软开源最强Python自动化神器Playwright(不用写一行代码)
Jan 05 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
?繁体转换的class
2006/10/09 PHP
隐性调用php程序的方法
2009/03/09 PHP
解析PHP实现下载文件的两种方法
2013/07/05 PHP
PHP实现通过正则表达式替换回调的内容标签
2015/06/15 PHP
php获取本机真实IP地址实例代码
2016/03/31 PHP
PHP 绘制网站登录首页图片验证码
2016/04/12 PHP
PHP类和对象相关系统函数与运算符小结
2016/09/28 PHP
php设计模式之工厂方法模式分析【星际争霸游戏案例】
2020/01/23 PHP
jquery实现弹出层遮罩效果的简单实例
2014/03/03 Javascript
JavaScript使用cookie实现记住账号密码功能
2015/04/27 Javascript
JSON字符串转JSON对象
2015/07/31 Javascript
用AngularJS的指令实现tabs切换效果
2016/08/31 Javascript
AngularJS实现用户登录状态判断的方法(Model添加拦截过滤器,路由增加限制)
2016/12/12 Javascript
微信小程序 在线支付功能的实现
2017/03/14 Javascript
浅谈sass在vue注意的地方
2017/08/10 Javascript
使用原生js+canvas实现模拟心电图的实例
2017/09/20 Javascript
微信网页授权并获取用户信息的方法
2018/07/30 Javascript
vue中过滤器filter的讲解
2019/01/21 Javascript
Vue从TodoList中学父子组件通信
2019/02/05 Javascript
react-intl实现React国际化多语言的方法
2020/09/27 Javascript
Python正则表达式匹配ip地址实例
2014/10/09 Python
Python IDLE入门简介
2017/12/08 Python
浅谈Python接口对json串的处理方法
2018/12/19 Python
python 使用paramiko模块进行封装,远程操作linux主机的示例代码
2020/12/03 Python
利用HTML5实现使用按钮控制背景音乐开关
2015/09/21 HTML / CSS
.NET面试题:什么是反射
2016/09/30 面试题
商务英语大学生职业生涯规划书范文
2014/01/01 职场文书
社区学习雷锋活动总结
2014/04/25 职场文书
青春演讲稿范文
2014/05/08 职场文书
公共机构节能宣传周活动总结
2014/07/09 职场文书
司机岗位职责说明书
2014/07/29 职场文书
聚众斗殴罪辩护词
2015/05/21 职场文书
暗恋桃花源观后感
2015/06/12 职场文书
2019年暑期安全广播稿!
2019/07/03 职场文书
Java版 单机五子棋
2022/05/04 Java/Android
Redis批量生成数据的实现
2022/06/05 Redis