基本表达式
with EXPR as VAR #其中EXPR为任意表达式,as VAR部分可无
BLOCK
with所求值的语句必须有两个方法,分别是:__enter__()
和__exit__()
一般执行过程:
- 计算
EXPR
,获取一个上下文管理器 - 调用上下文管理器的
__enter__()
方法 - 若表达式包含
as VAR
·,将EXPR
的返回值(__enter__()
的返回值)赋值给VAR
- 执行
BLOCK
- 调用
__exit__()
方法
文件操作
with-as语句最常见的用法。
with open('test.text') as f:
content = f.read
比try-finally
语句简洁很多
异常处理
如果执行BLOCK
的过程中出现了异常导致程序退出,那么异常的type
、value
和traceback
(即sys.excinfo()
的返回值,未出错时返回None)将作为参数传递给__exit__()
方法。
class Sample:
def __enter__(self):
return self
def __exit__(self, type, value, trace):
print('[[type]]:', type)
print('[[value]]:', value)
print('[[trace]]:', trace)
def do_some_actions(self):
test = 1/0 #除数为零,出现异常应当报错
return test
with Sample() as s:
s.do_some_actions()
代码运行结果:
上下文管理器对with-as的支持(待写)
contextlib模块包含三个对象:装饰器contextmanager、函数nested和上下文管理器closing
使用closing:
import contextlib
使用生成器装饰器(待写)
from contextlib import contextmanager
@contextmanager
def transaction(db):
db.begin()
try:
yield db
except:
db.rollback()
raise
else:
db.commit()