Python教程:with语句的用法

打印 上一主题 下一主题

主题 894|帖子 894|积分 2682

一 、with语句的原理

上下文管理协议(Context Management Protocol):包含方法 __enter__()和__exit__(),支持该协议的对象要实现这两个方法。
上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了__enter__()和__exit__()方法。上下文管理器定义执行with语句时要建立的运行时上下文,负责执行with语句块上下文中的进入与退出操作。通常使用with语句调用上下文管理器,也可以通过直接调用其方法来使用。
说完上面两个概念,我们再从with语句的常用表达式入手,一段基本的with表达式,其结构是这样的:
  1. with EXPR as VAR:
  2.    BLOCK
复制代码
其中EXPR可以是任意表达式;as VAR是可选的。其一般的执行过程是这样的:

  • 执行EXPR,生成上下文管理器context_manager;
  • 获取上下文管理器的__exit()__方法,并保存起来用于之后的调用;
  • 调用上下文管理器的__enter__()方法;如果使用了as子句,则将__enter__()方法的返回值赋值给as子句中的VAR;
  • 执行BLOCK中的表达式;
  • 不管是否执行过程中是否发生了异常,执行上下文管理器的__exit__()方法,__exit__()方法负责执行“清理”工作,如释放资源等。如果执行过程中没有出现异常,或者语句体中执行了语句break/continue/return,则以None作为参数调用__exit__(None, None, None);如果执行过程中出现异常,则使用sys.exc_info得到的异常信息为参数调用__exit__(exc_type, exc_value, exc_traceback);
  • 出现异常时,如果__exit__(type, value, traceback)返回False,则会重新抛出异常,让with之外的语句逻辑来处理异常,这也是通用做法;如果返回True,则忽略异常,不再对异常进行处理。
二、自定义上下文管理器

Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。
  1. class DBManager(object):
  2.     def __init__(self):
  3.         pass
  4.     def __enter__(self):
  5.         print('__enter__')
  6.         return self
  7.     def __exit__(self, exc_type, exc_val, exc_tb):
  8.         print('__exit__')
  9.         return True
  10. def getInstance():
  11.         return DBManager()
  12. with getInstance() as dbManagerIns:
  13.     print('with demo')
复制代码
with后面必须跟一个上下文管理器,如果使用了as,则是把上下文管理器的 __enter__() 方法的返回值赋值给 target,target 可以是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)
代码运行结果如下:
  1. '''
  2. __enter__
  3. with demo
  4. __exit__
  5. '''
复制代码
结果分析:当我们使用with的时候,__enter__方法被调用,并且将返回值赋值给as后面的变量,并且在退出with的时候自动执行__exit__方法
  1. '''
  2. 学习中遇到问题没人解答?小编创建了一个Python学习交流群:711312441
  3. 寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
  4. '''
  5. class With_work(object):
  6.     def __enter__(self):
  7.         """进入with语句的时候被调用"""
  8.         print('enter called')
  9.         return "xxt"
  10.     def __exit__(self, exc_type, exc_val, exc_tb):
  11.         """离开with的时候被with调用"""
  12.         print('exit called')
  13. with With_work() as f:
  14.     print(f)
  15.     print('hello with')
复制代码
  1. '''
  2. enter called
  3. xxt
  4. hello with
  5. exit called
  6. '''
复制代码
三、总结

自定义上下文管理器来对软件系统中的资源进行管理,比如数据库连接、共享资源的访问控制等。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

守听

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表