例子一

首先来看一段代码:

classFoo(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__方法

这也就是为什么会出现文章开头的情况的原因。

例子二

再看看这段代码:

classFoo(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:raiseImportErrorprint('正在执行')

结果如下:

把上面代码中我们注释掉的那一行代码取消注释,结果如下

我们会发现,虽然我们故意在语句体中抛出一个错误,按照正常情况,执行到报错地方就不会执行了,而__exit__是在语句体执行完之后执行的,但还是执行了__exit__方法;当我们在__exit__中给一个返回值为Ture时,就会忽略错误。

结论2

所有我们可以发现

with语句类似

try :

except:

finally:

的功能:但是with语句更简洁。而且更安全。代码量更少。

出现异常时,如果 __exit__ 返回 False(默认不写返回值时,即为False),则会重新抛出异常,让with 之外的语句逻辑来处理异常,这也是通用做法;如果返回 True,则忽略异常,不再对异常进行处理

例子三

classFoo(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 insomefile:printline#...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进入上下文管理器_浅谈Python中with(上下文管理器)的用法相关推荐

  1. python中rstrip用法_浅谈Python3中strip()、lstrip()、rstrip()用法详解

    简单来说,三种方法是为了删除字符串中不同位置的指定字符.其中,strip()用于去除字符串的首尾字符,同理,lstrip()用于去除左边的字符,rstrip()用于去除右边的字符 Python中有三个 ...

  2. python脚本开头怎么写_浅谈Python脚本开头及导包注释自动添加方法

    浅谈Python脚本开头及导包注释自动添加方法 1.开头:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 指定 #!/usr/bin/python 是用来 ...

  3. python生成器和迭代器作用_浅谈Python中的生成器和迭代器

    迭代器 迭代器协议 对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么返回一个异常来终止本次迭代.(只能往前走,不能往后退!) 迭代器对象 遵循了(实现了)迭代器协议的对象.(对象内 ...

  4. python 字典键值重复_浅谈python字典多键值及重复键值的使用

    在python中使用字典,格式如下: dict={ key1:value1 , key2;value2 ...} 在实际访问字典值时的使用格式如下: dict[key] 多键值 字典的多键值形式如下: ...

  5. python读取json数据格式问题_浅谈Python中的异常和JSON读写数据的实现

    异常可以防止出现一些不友好的信息返回给用户,有助于提升程序的可用性,在java中通过try ... catch ... finally来处理异常,在Python中通过try ... except .. ...

  6. python语言源程序文件类型_浅谈Python的文件类型

    Python的文件类型主要分为3种:源代码(source file).字节码(byte-code file).优化的字节码(optimized file).这些代码都可以直接运行,不需要编译或者连接. ...

  7. python如何导入requests模块_浅谈python中requests模块导入的问题

    浅谈python中requests模块导入的问题 今天使用Pycharm来抓取网页图片时候,要导入requests模块,但是在pycharm中import requests 时候报错. 原因: pyt ...

  8. python出现traceback什么意思_浅谈python出错时traceback的解读

    写 Python 代码的时候,当代码中出现错误,会在输出的时候打印 Traceback  错误信息,很多初学者看到那一堆错误信息,往往都会处于懵逼状态,脑中总会冒出一句,这都是些啥玩意.如果你是第一次 ...

  9. python异常处理机制的好处_浅谈Python异常处理机制

    异常机制己经成为衡量一门编程语言是否成熟的标准之一,使用异常处理机制的 Python 程序有更好的容错性,更加健壮. 对于计算机程序而言,情况就更复杂了一一没有人能保证自己写的程序永远不会出辛苦!就算 ...

最新文章

  1. 微生物分类学研究利器:模式微生物基因组数据库
  2. APT案例之点击事件
  3. Linux虚拟内存与线性地址翻译
  4. map集合怎么取value值最大的前三_Java之集合(下)
  5. oracle语句取字段前2位,oracle截取某一个字符之前或之后的值;substr();instr()
  6. 限定通配符和非限定通配符_为什么我不信任通配符以及为什么我们仍然需要通配符...
  7. java+session+存在哪_JAVA中Session
  8. 利用正则计算输入内容的长度
  9. GitHub Universe 2019 Keynote 回顾
  10. golang隐藏window系统下自身cmd窗口
  11. 用python写家族树的基本事实
  12. 职业规划 思维导图
  13. bat文件刷屏,请规范命名
  14. html引入let,let.html
  15. 终端I/O termios属性设置 tcsetattr设置
  16. html页面中引入自签名证书的js web资源出现net::ERR_CERT_AUTHORITY_INVALID
  17. 真c++ 从二叉树到红黑树(3)之二叉搜索树BST
  18. Qt5生成Word格式报告
  19. vue+百度地图实现搜索功能
  20. 基于SSM汽车维修管理系统-连锁店版

热门文章

  1. 调试中除了在URL上加时间戳外,如何避免js、css被返回304状态?
  2. blog.1z5k.com
  3. C#中执行Dos命令
  4. 解决硬盘磁道损坏问题(亲测)
  5. Ubuntu18.04取消VIM自动备份文件
  6. Pulseaudio调用alsalib write()流程(十六)
  7. Vysor 2.1.x Pro使用
  8. Mac下Android Studio快捷键
  9. Android7.1 Audio的FW和HAL层dump PCM数据(三十七)
  10. Windows10---开启FTP服务与配置