浅淡python中的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
浅淡python中的with,上下文管理器的更多相关文章
- Python进阶——什么是上下文管理器?
在 Python 开发中,我们经常会使用到 with 语法块,例如在读写文件时,保证文件描述符的正确关闭,避免资源泄露问题. 你有没有思考过, with 背后是如何实现的?我们常常听到的上下文管理器究 ...
- Python: 浅淡Python中的属性(property)
起源:项目过程中需要研究youtube_dl这个开源组件,翻阅其中对类的使用,对比c#及Delphi中实现,感觉Python属性机制挺有意思.区别与高级编程语言之单一入口,在类之属性这一方面,它随意的 ...
- python2.7高级编程 笔记一(Python中的with语句与上下文管理器学习总结)
0.关于上下文管理器上下文管理器是可以在with语句中使用,拥有__enter__和__exit__方法的对象. with manager as var: do_something(var) 相当于以 ...
- asyncio之异步上下文管理器
异步上下文管理器 前面文章我们提到了上下文管理器,但是这个上下文管理器只适用于同步代码,不能用于异步代码(async def形式),不过不用担心今天我们就来讨论在异步中如何使用上下文管理器. 特别提醒 ...
- (转)contextlib — 上下文管理器工具
原文:https://pythoncaff.com/docs/pymotw/contextlib-context-manager-tool/95 这是一篇社区协同翻译的文章,你可以点击右边区块信息里的 ...
- 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中实现了__enter__和__exit__方法的对象就可以称之为上下文管理器 实现方法一举例: def File(object): def __init__(self, ...
随机推荐
- Android 7.1 WindowManagerService 屏幕旋转流程分析 (二)
一.概述 从上篇[Android 7.1 屏幕旋转流程分析]知道实际的旋转由WindowManagerService来完成,这里接着上面具体详细展开. 调了三个函数完成了三件事,即首先调用update ...
- Android之通过网络播放一首简单的音乐
首先,附上程序执行后的效果.例如以下图所看到的: 一.部署一个web项目到tomcatserver上: 1.这个小程序是结合网络来播放一首音乐的,首先,把我们搞好的一个web项目放置在tomcat安装 ...
- 基于C++11的线程池
1.封装的线程对象 class task : public std::tr1::enable_shared_from_this<task> { public: task():exit_(f ...
- Objective-C基础语法高速入门
Objective-C是Mac软件开发领域最基本的开发语言,假如我们对C语言已经非常熟悉或者具有面向对象语言的基础.对于我们学习Objective-C将会非常实用. 方法调用(Calling Meth ...
- mysql中对字符集和校对规则的认识
字符集:指符号和字符编码的集合.校对规则:比较字符编码的方式.GBK2312:主要包括简体中文字符及常用符号,对于中文字符采用双字节编码的格式,也就是说一个汉字字符在存储占两个字节.GBK:包括有中. ...
- wordpess关闭评论的方法,wordpress开发
由于某种原因,需要把wordpress的评论关闭,下面讲一下方法. 在wordpress模板中,找到文章模板页面文件single.php,在里面找到 <?php comments_templat ...
- 青否云 - 小程序待办事项 wxapp开源系统
青否云最新开源系统:小程序待办事项 wxapp-demo 青否云 小程序 demo 下载地址:https://github.com/qingful/wxapp-demo 官网 http://cloud ...
- org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
异常信息 org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable represen ...
- 截屏 iOS
#pragma mark - 截屏 + (UIImage *_Nonnull)screenShotWithController:(UIViewController *_Nonnull)controll ...
- 嵌套查询别名必须性示例。HAVING用法
HAVING的一个重要作用: SELECT子句有统计函数嵌套时SELECT子句不能出现GROUP BY列,如果需要显示此列可以把嵌套的统计函数写成子查询放在HAVING子句中. 可用HAVING简化语 ...