with正确使用——测试工程师Python开发实战(14)

发表于:2023-8-23 09:52

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:胡通    来源:51Testing软件测试网原创

#
Python
  4.10  with正确使用
  任何一门编程语言中,文件的输入输出、数据库的连接断开等,都是很常见的资源管理操作。但资源是有限的,在编写代码时,必须保证这些资源在使用后得到释放,不然容易造成资源泄漏,轻者使得系统处理缓慢,严重时会使系统崩溃。
  为了更好地避免此类问题,不同的编程语言引入了不同的机制。在Python中,对应的解决方式是使用with as语句操作上下文管理器,上下文管理器能够帮助我们自动分配并且释放资源。有一些任务可能事先需要设置,事后做清理工作。对于这种场景,Python的with as语句提供了一种非常方便的处理方式。例如,使用with as语句操作已经打开的文件对象,无论程序运行期间是否抛出异常,都保证with as语句执行完毕后自动关闭已经打开的文件。
  除了有更优雅的语法,with as语句还可以很好地处理上下文环境产生的异常。with as语句通过__enter__()方法初始化,然后在__exit__()中做善后和异常处理,所以使用with处理的对象必须有__enter__()和__exit__()这两个方法。
  with as语句的语法格式如下:
with expression [as target]:
    with_body
  参数说明如下:
  expression是一个需要执行的表达式;
  target是一个变量或元组,存储的是expression表达式执行后返回的结果,[]表示该参数为可选参数。
  with as语句的执行流程如下。
  (1)运行expression表达式,如果表达式含有计算、类初始化等内容,将优先执行。
  (2)运行内置的__enter__()方法中的代码。
  (3)运行with_body中的代码。
  (4)运行__exit__()方法中的代码进行善后,如释放资源、处理错误等。
  示例如下:
#!/usr/bin/env python
class Sample:
    def __enter__(self):
        return self
    def __exit__(self, type, value, trace):
        print "type:", type
        print "value:", value
        print "trace:", trace
    def do_something(self):
        bar = 1/0
        return bar + 10
with Sample() as sample:
    sample.do_something()
  在示例中,只要紧跟with后面的语句所返回的对象有__enter__()和__exit__()方法即可实现上下文资源的管理。此例中,Sample()的__enter__()方法返回新创建的Sample对象,并赋值给变量sample。代码执行后输出如下:
type: <type 'exceptions.ZeroDivisionError'>
value: integer division or modulo by zero
trace: <traceback object at 0x1004a8128>
Traceback (most recent call last):
  File "./with_example02.py", line 19, in <module>
    sample.do_something()
  File "./with_example02.py", line 15, in do_something
    bar = 1/0
ZeroDivisionError: integer division or modulo by zero
  实际上,在with的代码块抛出异常时,__exit__()方法将被执行。正如示例中,异常抛出时,与之关联的type、value和stack trace传入__exit__()方法,因此抛出的ZeroDivisionError异常被输出。在开发模块时,清理资源、关闭文件等操作都可以放在__exit__()方法当中。
  因此,Python的with as语句提供了一个有效的让代码更简练的机制,同时让异常产生时的清理工作更简单。
  此外,with as语句支持嵌套多环境管理器,语法如下:
with A() as a, B() as b:
 ...statements...
  它等价于嵌套的with as语句:
with A() as a:
  with B() as b:
  ...statements...
  多环境管理器管理的多个对象会在with as语句的代码块出现异常时,或者执行完with as语句的代码块时全部自动被清理。
  例如,打开两个文件,将它们的内容通过zip()合并在一起,然后同时关闭它们:
with open('a.file') as f1, open('b.file') as f2:
   for pair in zip(f1, f2):
      print(pair)
  总结一下,with语句适用于需要访问资源的场景,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,以释放资源,例如文件使用后自动关闭、线程中锁的自动获取和释放等。
版权声明:51Testing软件测试网获得作者授权连载本书部分章节。
任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号