Python中with用法详解
阅读目录(Content)
一 、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
语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。
# coding = utf-8 # 2019/7/19 Luckyxxt:有趣的事,Python永远不会缺席! #!/usr/bin/env python class DBManager(object): def __init__(self): pass def __enter__(self): print(‘__enter__‘) return self def __exit__(self, exc_type, exc_val, exc_tb): print(‘__exit__‘) return True def getInstance(): return DBManager() with getInstance() as dbManagerIns: print(‘with demo‘)
with后面必须跟一个上下文管理器,如果使用了as,则是把上下文管理器的 __enter__() 方法的返回值赋值给 target,target 可以是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)
代码运行结果如下:
‘‘‘ __enter__ with demo __exit__ ‘‘‘
结果分析:当我们使用with的时候,__enter__方法被调用,并且将返回值赋值给as后面的变量,并且在退出with的时候自动执行__exit__方法
class With_work(object): def __enter__(self): """进入with语句的时候被调用""" print(‘enter called‘) return "xxt" def __exit__(self, exc_type, exc_val, exc_tb): """离开with的时候被with调用""" print(‘exit called‘) with With_work() as f: print(f) print(‘hello with‘)
‘‘‘ enter called xxt hello with exit called ‘‘‘
三、总结
自定义上下文管理器来对软件系统中的资源进行管理,比如数据库连接、共享资源的访问控制等。
转自:https://www.cnblogs.com/xxtalhr/p/11211347.html#_labelTop
相关推荐
wpfeitian 2020-09-28
wangrui0 2020-07-05
qiximiao 2020-07-05
CSSEIKOCS 2020-06-25
邓博学习笔记 2020-06-15
fenxinzi 2020-06-15
bluecarrot 2020-06-15
onlykg 2020-06-14
cwgxiaoguizi 2020-06-14
atb 2020-06-14
Attend 2020-06-14
咏月东南 2020-06-14
citic 2020-06-14
NeverAgain 2020-06-14
heheeheh 2020-06-14
hickwu 2020-06-14
pointfish 2020-06-14
YoungkingWang 2020-06-13