python中的with的用法,上下文管理器
with是从Python2.5引入的一个新的语法,它是一种上下文管理协议,目的在于从流程图中把 try,except 和finally 关键字和
资源分配释放相关代码统统去掉,简化try….except….finlally的处理流程。
with通过__enter__方法初始化,然后在__exit__中做善后以及处理异常。
所以使用with处理的对象必须有__enter__()和__exit__()这两个方法。
其中__enter__()方法在语句体(with语句包裹起来的代码块)执行之前进入运行,__exit__()方法在语句体执行完毕退出后运行。
with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。
首先来看一段代码:

- class Foo(object):
- def __init__(self):
- print('实例化一个对象')
- def __enter__(self):
- print('进入')
- def __exit__(self, exc_type, exc_val, exc_tb):
- print('退出')
- obj = Foo()
- with obj:
- print('正在执行')

上面代码执行结果为:
- 实例化一个对象
- 进入
- 正在执行
- 退出
结论1
我们知道,实例化Foo,得到obj对象,会执行Foo的__init__方法,也就是打印了第一句;
按照,程序从上至下执行,应该会打印“正在执行”才对,为什么会在它之前先打印了进入,在它之后打印了退出呢?
因为我们在定义Foo时,定义了__enter__和__exit__方法,那么我们实例化的对象obj就是一个上下文管理器,
即含有__enter__和__exit__方法的对象就是上下文管理器。
- with 上下文管理器:
- 语句体
当with遇到上下文管理器,就会在执行语句体之前,先执行上下文管理器的__enter__方法,然后再执行语句体,执行完语句体后,最后执行__exit__方法
这也就是为什么会出现文章开头的情况的原因。
再看看这段代码:

- class Foo(object):
- def __init__(self):
- print('实例化一个对象')
- def __enter__(self):
- print('进入')
- def __exit__(self, exc_type, exc_val, exc_tb):
- print('退出')
# return True- obj = Foo()
- with obj:
- raise ImportError
- print('正在执行')

结果如下:
把上面代码中我们注释掉的那一行代码取消注释,结果如下
我们会发现,虽然我们故意在语句体中抛出一个错误,按照正常情况,执行到报错地方就不会执行了,而__exit__是在语句体执行完之后执行的,但还是执行了__exit__方法;当我们在__exit__中给一个返回值为Ture时,就会忽略错误。
结论2
所有我们可以发现
with语句类似
try :
except:
finally:
的功能:但是with语句更简洁。而且更安全。代码量更少。
出现异常时,如果 __exit__ 返回 False(默认不写返回值时,即为False),则会重新抛出异常,让with 之外的语句逻辑来处理异常,这也是通用做法;如果返回 True,则忽略异常,不再对异常进行处理

- class Foo(object):
- def __init__(self):
- print('实例化一个对象')
- def __enter__(self):
- print('进入')
- # return self
- def __exit__(self, exc_type, exc_val, exc_tb):
- print('退出')
- with Foo() as obj:
- print(obj,type(obj))
- print('正在执行')

把上面代码中我们注释掉的那一行代码取消注释,结果如下
结论
调用上下文管理器的 __enter__ 方法时;如果使用了 as 子句,则将 __enter__() 方法的返回值赋值给 as 子句中的目标
- with 上下文管理器 as target:
- 代码语句体
with后面必须跟一个上下文管理器,如果使用了as,则是把上下文管理器的 __enter__() 方法的返回值赋值给 target,target 可以是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)
我们经常会看到这样的代码:
- with open("/tmp/foo.txt") as file:
- data = file.read()
结论
这里使用了 with 语句,不管在处理文件过程中是否发生异常,都能保证 with 语句执行完毕后已经关闭了打开的文件句柄。如果使用传统的 try/finally 范式,则要使用类似如下代码:

- somefile = open(r'somefileName')
- try:
- for line in somefile:
- print line
- # ...more code
- finally:
- somefile.close()

比较起来,使用 with 语句可以减少编码量。已经加入对上下文管理协议支持的还有模块 threading、decimal 等。
with只能配合上下文管理器使用,常见的上下文管理器有

- file
- decimal.Context
- thread.LockType
- threading.Lock
- threading.RLock
- threading.Condition
- threading.Semaphore
- threading.BoundedSemaphore
- 转载:https://www.cnblogs.com/huchong/p/8268765.html
python中的with的用法,上下文管理器的更多相关文章
- python2.7高级编程 笔记一(Python中的with语句与上下文管理器学习总结)
0.关于上下文管理器上下文管理器是可以在with语句中使用,拥有__enter__和__exit__方法的对象. with manager as var: do_something(var) 相当于以 ...
- Python高级语法-私有属性-with上下文管理器(4.7.3)
@ 目录 1.说明 2.代码 关于作者 1.说明 上下文管理器 这里使用with open操作文件,让文件对象实现了自动释放资源.我们也能自定义上下文管理器,通过__enter__()和__exit_ ...
- Python中的with语句(上下文管理协议)
在平时工作中总会有这样的任务,它们需要开始前做准备,然后做任务,然后收尾清理....比如读取文件,需要先打开,读取,关闭 这个时候就可以使用with简化代码,很方便 1.没有用with语句 f = o ...
- python之小记with open...as..上下文管理器
之前在学习file文件对象是说过,open文件操作结束后要关闭文件,否则会一直占用资源.但是当出现异常,如读取过程中文件不存在或异常,则直接出现错误,close方法无法执行,文件无法关闭 with o ...
- 『流畅的Python』第15章:上下文管理器和else块
- Python中的上下文管理器和with语句
Python2.5之后引入了上下文管理器(context manager),算是Python的黑魔法之一,它用于规定某个对象的使用范围.本文是针对于该功能的思考总结. 为什么需要上下文管理器? 首先, ...
- 深入理解 Python 中的上下文管理器
提示:前面的内容较为基础,重点知识在后半段. with 这个关键字,对于每一学习Python的人,都不会陌生. 操作文本对象的时候,几乎所有的人都会让我们要用 with open ,这就是一个上下文管 ...
- (转)Python中的上下文管理器和Tornado对其的巧妙应用
原文:https://www.binss.me/blog/the-context-manager-of-python-and-the-applications-in-tornado/ 上下文是什么? ...
- Python 的上下文管理器是怎么设计的?
花下猫语:最近,我在看 Python 3.10 版本的更新内容时,发现有一个关于上下文管理器的小更新,然后,突然发现上下文管理器的设计 PEP 竟然还没人翻译过!于是,我断断续续花了两周时间,终于把这 ...
- python上下文管理器ContextLib及with语句
http://blog.csdn.net/pipisorry/article/details/50444736 with语句 with语句是从 Python 2.5 开始引入的一种与异常处理相关的功能 ...
随机推荐
- iOS10推送必看UNNotificationAttachment以及UNTimeIntervalNotificationTrigger
虽然这篇文章比较长,也不好理解,但是还是建议大家收藏,以后用到的时候,可以看看,有耐心的还是读一读. 这篇文章开始,我会跟大家好好讲讲,苹果新发布的iOS10的所有通知类. 一.创建本地通知事例详解: ...
- Java集合框架介绍。Java Collection Frameworks = JCF
Java集合框架 = Java Collection Frameworks = JCF . 为了方便理解,我画了一张思维脑图.
- 安装xshell、xftp
1.Xshell的软件的下载.安装 xshell是一个终端模拟软件,而且是远程近程都可以. 就是模拟服务器所在的linux,在xshell中可以输入命令, 就像在服务器的linux中输入命令一样.一般 ...
- python urllib应用
urlopen 爬取网页 爬取网页 read() 读取内容 read() , readline() ,readlines() , fileno() , close() :这些方法的使用方式与文件对象完 ...
- const变量可以修改么?
遇到了一个关于const修饰的变量值是否能修改问题,虽然我知道const变量在某些情况下可以通过指向它的指针来间接修改,但是对原理还是很模糊,今天就整理了一下. 一.三个试验压压惊 1.直接对cons ...
- C++——友元 friend
人类社会的friend VS C++世界的friend 现实世界中,我们自己很多物品,朋友是可以使用的,但是陌生人就不行.那么money,朋友可以随便拿吗?这要是你和friend的关系深浅而定.人类社 ...
- nginx配置文件详解【nginx.conf】
#基本配置: #user nobody;#配置worker进程运行用户worker_processes 1;#配置工作进程数目,根据硬件调整.通常等于CPU数量或者2倍于CPU数量 比如四核电脑(可以 ...
- 如何使用Feign构造多参数的请求
原文:http://www.itmuch.com/spring-cloud-sum/feign-multiple-params/ 本节来探讨如何使用Feign构造多参数的请求.笔者以GET及POST请 ...
- How to parse unix timestamp to time.Time
The time.Parse function does not do Unix timestamps. Instead you can use strconv.ParseInt to parse ...
- springboot的入门
SpringBoot SpringBoot是SpringMVC的升级版,简化配置,很可能成为下一代的框架 1.新建项目 怎么创建springBoot项目呢? 创建步骤复杂一点点 New Project ...