Python中的上下文管理器和with语句的使用


Posted in Python onApril 17, 2018

Python2.5之后引入了上下文管理器(context manager),算是Python的黑魔法之一,它用于规定某个对象的使用范围。本文是针对于该功能的思考总结。

为什么需要上下文管理器?

首先,需要思索下为什么需要引入上下文管理器。

在正常情况下,管理各种系统资源(如文件)、数据库连接时,通常是先打开这些资源,执行完相应的业务逻辑,最后关闭资源。

举两个例子:

1.使用Python打开一个文件写入内容,之后需要关闭这个文件。如果不正常关闭的话可能会在文件操作时出现异常,因为系统允许你打开的文件的最大数是有限的。

2.在数据库连接时也是存在类似问题,数据库的连接算是一种比较昂贵的资源,若连接过多而没有及时关闭的话,就可能出现不能继续连接的异常错误。

但是,很多程序员经常会忘记关闭文件,或者关闭数据库的连接。这时候就引入了上下文管理器,它可以在你不需要该对象的时候,自动关闭它。

上下文管理器怎么使用?

上下文管理器的语法是:with...as...

实例:文件操作

print "不使用上下文管理器"
print "*" * 30
f = open('file.py', 'w')
print f.closed
f.write("# Hello World")
f.close()
print f.closed

print "\n使用上下文管理器"
print "*" * 30
with open("file.py", 'w') as f:
  print f.closed
  f.write('# Hello Python')
print f.closed

这里通过.closed比较,我们可以看到上下文管理器可以自动关闭文件,对于上下文管理器而言,有隶属于它的程序块,当隶属于它的程序块执行结束的时候(判断缩进),上下文管理器将自动关闭文件。
 上述实例,也可以使用try...except...来实现,同样可以很直观的看到使用with...as...语句之后,代码确实相对更加简洁。

上下文管理实现机制

因为文件对象是Python的内置对象,内置了上下文管理的特殊方法,所以它可以使用with语句。在Python中,任何对象,只要实现了上下文管理,就可以使用with语句,实现上下文管理需要通过__enter__和__exit__这两个方法来实现。

关于这两个方法:

  1. enter(self):进入该对象时调用此方法,返回值将放入with...as...语句中的as说明的变量中
  2. exit(self, type, value, tb):离开上下文管理器时调用该方法,如果有异常出现,返回False,type、value和tb将分别表示异常的类型、值和追踪信息,传递出上下文显示;如果没有异常,则三个变量的值均为None。

with 上下文管理器:
    语法体

当with语句遇到上下文管理器时,就会在执行语法体之前,先执行__enter__方法,然后再执行语法体,执行完语法体之后,执行__exit__方法。

上下文管理器实现

使用Python2.7X实现一个上下文管理器:

class Context(object):

  def __init__(self):
    print "实例化一个对象"

  def __enter__(self):
    print "获取该对象"

  def __exit__(self, exc_type, exc_val, exc_tb):
    print "退出该对象"

temp = Context()

with temp:
  print "执行体"

这样,__enter__方法和__exit__方法的调用过程就很明晰。

contextLib

在contextlib中,提供了contextmanager装饰器,通过yield返回函数将函数分隔为两部分,yield之前的语句在__enter__中执行,yield之后的语句在__exit__中执行,简化了上下文管理器的实现方式:

总结:通过上下文管理器,我们可以更好的控制对象在不同区间的特性,并且可以使用with语句替代try...except方法,使得代码更加的简洁,主要的使用场景是访问资源,可以保证不管过程中是否发生错误或者异常都会执行相应的清理操作,释放出访问的资源。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python搭建APNS苹果推送通知推送服务的相关模块使用指南
Jun 02 Python
Python机器学习之SVM支持向量机
Dec 27 Python
Python爬虫实现百度图片自动下载
Feb 04 Python
Python(TensorFlow框架)实现手写数字识别系统的方法
May 29 Python
Python二进制串转换为通用字符串的方法
Jul 23 Python
python处理multipart/form-data的请求方法
Dec 26 Python
Python Flask框架模板操作实例分析
May 03 Python
Python获取好友地区分布及好友性别分布情况代码详解
Jul 10 Python
python 变量初始化空列表的例子
Nov 28 Python
np.random.seed() 的使用详解
Jan 14 Python
.img/.hdr格式转.nii格式的操作
Jul 01 Python
解决pytorch下出现multi-target not supported at的一种可能原因
Feb 06 Python
Python实现读取字符串按列分配后按行输出示例
Apr 17 #Python
一个简单的python爬虫程序 爬取豆瓣热度Top100以内的电影信息
Apr 17 #Python
Numpy掩码式数组详解
Apr 17 #Python
对numpy中布尔型数组的处理方法详解
Apr 17 #Python
Python简单实现阿拉伯数字和罗马数字的互相转换功能示例
Apr 17 #Python
python3库numpy数组属性的查看方法
Apr 17 #Python
对python中的for循环和range内置函数详解
Apr 17 #Python
You might like
浅谈php函数serialize()与unserialize()的使用方法
2014/08/19 PHP
php经典算法集锦
2015/11/14 PHP
yii2分页之实现跳转到具体某页的实例代码
2016/06/02 PHP
PHP文件打开关闭及读写操作示例解析
2020/08/06 PHP
JS在IE和FF下attachEvent,addEventListener学习笔记
2009/11/26 Javascript
js Event对象的5种坐标
2011/09/12 Javascript
自己写的兼容ie和ff的在线文本编辑器类似ewebeditor
2012/12/12 Javascript
jQuery+Ajax实现限制查询间隔的方法
2016/06/07 Javascript
基于JS实现类似支付宝支付密码输入框
2016/09/02 Javascript
js编写三级联动简单案例
2016/12/21 Javascript
详解VueJS 数据驱动和依赖追踪分析
2017/07/26 Javascript
关于vue.extend和vue.component的区别浅析
2017/08/16 Javascript
vue项目中使用ueditor的实例讲解
2018/03/05 Javascript
判断iOS、Android以及PC端的示例代码
2018/11/15 Javascript
微信公众号H5支付接口调用方法
2019/01/10 Javascript
Vue两个版本的区别和使用方法(更深层次了解)
2020/02/16 Javascript
JS Array.from()将伪数组转换成数组的方法示例
2020/03/23 Javascript
Element中Slider滑块的具体使用
2020/07/29 Javascript
python3实现名片管理系统
2020/11/29 Python
详解python持久化文件读写
2019/04/06 Python
Python爬虫图片懒加载技术 selenium和PhantomJS解析
2019/09/18 Python
Python双链表原理与实现方法详解
2020/02/22 Python
Tensorflow tf.nn.depthwise_conv2d如何实现深度卷积的
2020/04/20 Python
Scrapy+Selenium自动获取cookie爬取网易云音乐个人喜爱歌单
2021/02/01 Python
CSS3实现精美横向滚动菜单按钮
2017/04/14 HTML / CSS
利用CSS3动画实现圆圈由小变大向外扩散的效果实例
2018/09/10 HTML / CSS
Belle Maison倍美丛官网:日本千趣会旗下邮购网站
2016/07/22 全球购物
为您的家、后院、车库等在线购物:Spreetail
2019/06/17 全球购物
简单介绍Object类的功能、常用方法
2013/10/02 面试题
我能否用void** 指针作为参数, 使函数按引用接受一般指针
2013/02/16 面试题
应届毕业生自我鉴定范文
2013/12/27 职场文书
广告学专业求职信
2014/06/19 职场文书
教师业务学习材料
2014/12/16 职场文书
法律意见书范文
2015/06/04 职场文书
员工升职自我评价
2019/03/26 职场文书
Python+Appium新手教程
2021/04/17 Python