python里w_Python中with用法详解

一 、with语句的原理

上下文管理协议(Context Management Protocol):包含方法 __enter__()和__exit__(),支持该协议的对象要实现这两个方法。

上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了__enter__()和__exit__()方法。上下文管理器定义执行with语句时要建立的运行时上下文,负责执行with语句块上下文中的进入与退出操作。通常使用with语句调用上下文管理器,也可以通过直接调用其方法来使用。

说完上面两个概念,我们再从with语句的常用表达式入手,一段基本的with表达式,其结构是这样的:

1 with EXPR as VAR:2

3 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 #coding = utf-8

2 #2019/7/19 Luckyxxt:有趣的事,Python永远不会缺席!

3 #!/usr/bin/env python

4

5 classDBManager(object):6 def __init__(self):7 pass

8

9 def __enter__(self):10 print('__enter__')11 returnself12

13 def __exit__(self, exc_type, exc_val, exc_tb):14 print('__exit__')15 returnTrue16

17 defgetInstance():18 returnDBManager()19

20 with getInstance() as dbManagerIns:21 print('with demo')

with后面必须跟一个上下文管理器,如果使用了as,则是把上下文管理器的 __enter__() 方法的返回值赋值给 target,target 可以是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)

代码运行结果如下:

1 '''

2 __enter__3 with demo4 __exit__5

6 '''

结果分析:当我们使用with的时候,__enter__方法被调用,并且将返回值赋值给as后面的变量,并且在退出with的时候自动执行__exit__方法

1 classWith_work(object):2 def __enter__(self):3 """进入with语句的时候被调用"""

4 print('enter called')5 return "xxt"

6

7 def __exit__(self, exc_type, exc_val, exc_tb):8 """离开with的时候被with调用"""

9 print('exit called')10

11

12 with With_work() as f:13 print(f)14 print('hello with')

1 '''

2 enter called3 xxt4 hello with5 exit called6

7 '''

三、总结

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值