Python中的with语句用于用上下文管理器(context manager)定义的方法包装块的执行,它允许将常见的try…except…finally使用模式封装起来以方便重用。

在Python中,在处理非托管资源(unmanaged resources)(如文件流)时使用with关键字。它允许确保你在使用资源的代码完成运行时”清理”资源,即使抛出异常也是如此。它为try/finally块提供”语法糖”(syntactic sugar)。

with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的”清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。

要在用户定义的对象中使用with语句,你只需在对象方法中添加__enter__()和__exit__()方法。

with语法:

with EXPRESSION [as TARGET]:SUITE

with语句执行过程如下:

(1).评估上下文表达式以获得上下文管理器;

(2).上下文管理器的__enter__()被加载以备后用;

(3).上下文管理器的__exit__()被加载以备后用;

(4).上下文管理器的__enter__()方法被调用;

(5).如果TARGET包含在with语句中,则将__enter__()的返回值赋值给它。with语句保证如果__enter__()方法没有错误返回,那么__exit__()将始终被调用。因此,如果在赋值给TARGET列表的过程中发生错误,它将被视为SUITE中发生的错误。__enter__()方法是可以带返回值的,默认返回None。

(6).SUITE被执行;

(7).上下文管理器的__exit__()方法被调用。如果异常导致SUITE退出,则其类型、值和回溯(traceback)将作为参数传递给__exit__();否则,传递3个None。__exit__()方法也是可以带返回值的,这个返回值应该是一个布尔类型True或False,默认为None(即False)。如果为False,异常会被抛出,用户需要进行异常处理。如果为True,则表示忽略该异常。

如果SUITE因异常退出,并且__exit__()方法返回的值为False,则触发异常。如果返回值为True,则异常被抑制,并继续执行with语句之后的语句。

如果SUITE因异常以外的任何原因退出,则__exit__()的返回值将被忽略,并在所采取的退出类型的正常位置继续执行。

以上内容主要翻译于:https://docs.python.org/3/reference/compound_stmts.html#the-with-statement

以下为测试代码:

class FileWriter(object):def __init__(self, file_name):print("run __init__")self.file_name = file_namedef __enter__(self):print("run __enter__")self.file = open(self.file_name, 'w')return self.filedef __exit__(self, type, value, traceback):print("run __exit__")print("type:", type); print("value:", value); print("traceback:", traceback)self.file.close()print("test FileWriter:")
with FileWriter('tmp.txt') as f:print("start write")f.write('hello world')print("end write")class ExceptionTest(object):def __enter__(self):print("run __enter__")return selfdef __exit__(self, type, value, traceback):print("run __exit__")print("type:", type); print("value:", value); print("traceback:", traceback)return False # return True # 注意返回True和False的区别:返回True则跳过异常,继续执行with语句之后的语句def divide_by_0(self):v = 10/0print("\ntest ExceptionTest")
with ExceptionTest() as ex:ex.divide_by_0()print("test finish")

执行结果如下:

GitHub:https://github.com/fengbingchun/Python_Test

Python3中with用法相关推荐

  1. python中print的用法_Python2与Python3中print用法总结

    Python2中的print用法 在Python2 中 print 是一种输出语句 strHello = 'Hello Python' print strHello # Hello Python 1. ...

  2. python2和python3的区别 print-Python2与Python3中print用法总结

    Python2中的print用法 在Python2 中 print 是一种输出语句 strHello = "Hello Python" print strHello # Hello ...

  3. Python3中raise用法

          Python中raise语句支持强制触发指定的异常.       raise语法: raise [EXPRESSION [from EXPRESSION]]       如果raise后未 ...

  4. Python3中None用法

    1.None是一个空值,空值是Python里的一个特殊值,用None表示.可以将None赋值给任何变量. var = None; print(var) # None if var is None:pr ...

  5. Python3中省略号(...)用法介绍

    1. 省略号(...)是一个Python对象,叫Ellipsis,它没有方法,是一个单例对象(singleton object): # 1. ...是一个python对象,叫Ellipsis prin ...

  6. python3 中 阅读器reader的理解 以及 reader 的 next 用法

    python中有个csv包(build-in),该包有个reader,按行读取csv文件中的数据 reader.next()作用:打印csv文件中的第一行标题header python3中的用法: a ...

  7. python双除_python2和python3 中的除法的区别

    1. python2中有/和//的除法区别: 其中/的用法: >>>1/2 0 即一个整数(无小数部分的数)被另外一个整数除,计算结果的小数部分被截除了,只留下了整数部分 有时候,这 ...

  8. pythonurllib模块-Python3中核心模块urllib的用法大全

    Python的urllib模块提供了一个高级的Web通信库,支持基本的协议,如HTTP.FTP和Gopher,同时也支持对本地文件的访问.在Python3中,urllib.urlparse.urlli ...

  9. python3 yield 大文件_详解Python3中yield生成器的用法

    任何使用yield的函数都称之为生成器,如: def count(n): while n > 0: yield n #生成值:n n -= 1 另外一种说法:生成器就是一个返回迭代器的函数,与普 ...

最新文章

  1. 【PAT乙级】1001 害死人不偿命的(3n+1)猜想 (15 分)
  2. php layui ajax多图上传,Laravel+Layer实现图片上传功能(整理篇)
  3. Shape Drawable Xml的background
  4. python做的项目管理软件_幽雅的使用Python之软件管理
  5. MySQL软件的介绍
  6. 用Docker构建LNMP环境(上)
  7. mysql视图表修复_mysql中含有视图数据库在恢复数据时视图变成数据表的解决方法...
  8. 读懂 Redis 源码,我总结了这7点心得
  9. oppo r9 android7.0,OPPO R9 Plus的手机系统是什么
  10. 成功最快的就是改变你这个思维,拥有这个全新的思维
  11. Springmvc_3(SessionAttributes 将数据放入到session中)
  12. java ip解析_java域名解析
  13. 【OpenDDS开发指南V3.20】第一章:介绍
  14. 【专题5: 硬件设计】 之 【62.案例四:简易空气净化器,完整原理图】
  15. linux awk 打印最后一列,使用awk打印从第n个到最后一个的所有列
  16. js获取浏览器内核版本信息
  17. 华硕路由器里的虚拟服务器在哪里,华硕RT-AC86U路由器怎么设置端口转发服务
  18. 微信小程序中wxml中用data-id传出的数据在js中的获取方法
  19. Realsense-Ros安装配置
  20. 2020Android大厂高频面试题(字节跳动+阿里+华为+小米等20家大厂面试真题)附面经!

热门文章

  1. 解决ros安装 使用roscore命令测试问题
  2. 基于Struts2框架的名片管理系统
  3. GitHub开源城市结构公交路线数据可视化
  4. python输入多个数字后续操作_有效地确定后续数字范围中的数字是否在有序列表中. (在Python中)...
  5. 用c语言设计一个菜单界面_用这7个方法设计菜单,让餐厅的利润暴涨
  6. PCL采样一致性算法
  7. Udacity机器人软件工程师课程笔记(十三)-运动学-机械手介绍及分类
  8. Ubuntu 14.04 64bit上安装Scrapy
  9. C/C++面试题分享
  10. blender硬表面建模渲染终极教程