例子一

首先来看一段代码:

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,上下文管理器的更多相关文章

  1. Python进阶——什么是上下文管理器?

    在 Python 开发中,我们经常会使用到 with 语法块,例如在读写文件时,保证文件描述符的正确关闭,避免资源泄露问题. 你有没有思考过, with 背后是如何实现的?我们常常听到的上下文管理器究 ...

  2. Python: 浅淡Python中的属性(property)

    起源:项目过程中需要研究youtube_dl这个开源组件,翻阅其中对类的使用,对比c#及Delphi中实现,感觉Python属性机制挺有意思.区别与高级编程语言之单一入口,在类之属性这一方面,它随意的 ...

  3. python2.7高级编程 笔记一(Python中的with语句与上下文管理器学习总结)

    0.关于上下文管理器上下文管理器是可以在with语句中使用,拥有__enter__和__exit__方法的对象. with manager as var: do_something(var) 相当于以 ...

  4. asyncio之异步上下文管理器

    异步上下文管理器 前面文章我们提到了上下文管理器,但是这个上下文管理器只适用于同步代码,不能用于异步代码(async def形式),不过不用担心今天我们就来讨论在异步中如何使用上下文管理器. 特别提醒 ...

  5. (转)contextlib — 上下文管理器工具

    原文:https://pythoncaff.com/docs/pymotw/contextlib-context-manager-tool/95 这是一篇社区协同翻译的文章,你可以点击右边区块信息里的 ...

  6. Python中的上下文管理器和with语句

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

  7. 深入理解 Python 中的上下文管理器

    提示:前面的内容较为基础,重点知识在后半段. with 这个关键字,对于每一学习Python的人,都不会陌生. 操作文本对象的时候,几乎所有的人都会让我们要用 with open ,这就是一个上下文管 ...

  8. (转)Python中的上下文管理器和Tornado对其的巧妙应用

    原文:https://www.binss.me/blog/the-context-manager-of-python-and-the-applications-in-tornado/ 上下文是什么? ...

  9. python中实现上下文管理器的两种方法

    上下文管理器: python中实现了__enter__和__exit__方法的对象就可以称之为上下文管理器 实现方法一举例: def File(object): def __init__(self, ...

随机推荐

  1. Scala并发编程react、loop代码实战具体解释

    演示样例代码及凝视: //scala并发编程中的react和loop,共同特点: //通过线程存用的方式让性能有所提升. //Actor本身的运行,被actor子系统管理的时候,会有一个或者多个远程的 ...

  2. 使用asyncsocket群聊

    #import "ViewController.h" #import "AsyncSocket.h" @interface ViewController ()& ...

  3. iOS旋钮动画-CircleKnob

    欢迎相同喜欢动效的project师/UI设计师/产品添加我们 iOS动效特攻队–>QQ群:547897182 iOS动效特攻队–>熊熊:648070256 前段时间和群里的一个设计师配合. ...

  4. 彻底弄懂 JavaScript 执行机制

    本文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我. 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定 ...

  5. 大白话Vue源码系列(03):生成render函数

    阅读目录 优化 AST 生成 render 函数 小结 本来以为 Vue 的编译器模块比较好欺负,结果发现并没有那么简单.每一种语法指令都要考虑到,处理起来相当复杂.上篇已经生成了 AST,本篇依然对 ...

  6. 超详细的 Linux CentOS 编译安装python3

    前言: 安装完CentOS7后,执行#Python与#python -V,看到版本号是2.6,而且之前写的都是跑在python3.X上面的,3.X和2.X有很多不同,在这里我就不弊述两者之间的区别了新 ...

  7. IDEA使用有道翻译插件

    使用IDEA编写代码或者查看源码的时候有时候需要使用的翻译功能,虽然已经有繁多的翻译服务提供了桌面版的软件,但是并不大适合使用在阅读或者编写代码这个场景.IDEA丰富的插件库为我们提供了一些翻译插件, ...

  8. 《Netty5.0架构剖析和源码解读》【PDF】下载

    <Netty5.0架构剖析和源码解读>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062545 内容简介 Netty 是个异步的 ...

  9. 推荐的五款市面上常用的免费CMS建站系统

    我做设计也有不少年头了,很多客户或者朋友找我做网站的时候,一般问我的是用什么软件系统给他们做.大部分客户希望用的软件是免费的.所以今天给大家介绍五款我自己用过还不错的,重点是还免费的建站系统. Met ...

  10. iOS 页面之间的专长动画控制器间的转换

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 24.0px; font: 14.0px "Heiti SC Light" ...