with语句
使用with语句可以在上下文管理器对象控制的运行环境上下文中执行一系列语句,在进入与退出环境时,自动执行一些语句
# with 上下文管理对象:
# do.....
上下文管理对象
使用with语句,必须了解上下文管理对象,上下文管理对象就是支持上下文管理协议的对象,该协议主要是包含两个方法:__enter__()
,__exit__()
,
__enter()__
进入with
语句块时执行__exit__()
离开with
语句块时执行
上下文管理对象示例
# 定义一个类, 包含__enter__、__exit__两个方法
class A(object):
def __enter__(self):
self.__state__ = "Open"
return self
def __exit__(self, *args):
print(args)
self.__state__ = "Close"
定义了一个类对象A,包含了__enter__
,__exit__
两个方法,A的实例就是一个上下文管理对象,我们可以看到进入with
与退出with
时,__state__
值会发生变化
with语句示例
# 在with部分, a的状态就是OPEN
with A() as a:
# 进入with语句块
print(a.__state__) # 输出“Open"
# 离开了with语句,a的状态就变成了close
print(a.__state__) # 输出 "Close"
with语句中的异常
__exit__
方法包含三个参数:错误类型errortype
, 错误值value
,跟踪信息traceback
# with语句的异常处理
class A(object):
def __enter__(self):
self.__state__ = "Open"
return self
def __exit__(self, errortype, value, traceback):
print("type:", errortype)
print("value:", value)
print("traceback:", traceback)
self.__state__ = "Close"
with语句块中无异常示例
# 没有异常时的输出
with A() as a:
print(a.__state__)
print(a.__state__)
输出结果:
Open
type: None
value: None
traceback: None
Close
with语句块异常示例
# 出现异常时的提示
# 使用raise人为产生一个错误
with A() as a:
raise RuntimeError("发生运行时错误") # 人为抛出一个异常
print(a.__state__)
print(a.__state__)
输出结果:
type: <class 'RuntimeError'>
value: 发生运行时错误
....
由此,可以在退出时,监控程序运行状况,并进行异常处理
文件对象举例
文件对象支持上下文管理协议
不使用with语句
不使用with语句的写法,文件资源使用完毕后需要close,释放文件资源,这个有些情况下,可能容易忘记
f = open("myfile", "a+")
f.write("...")
f.close() # 忘记这一句,程序会一直执行到结束才会释放文件资源
使用with语句
使用with语句,close语句就可以省略了,在__exit__中会自动close文件对象资源
with open("myfile", "a+") as f:
f.write("......")
通过with语句,可以防止资源因为异常一直被占用,或者死锁状态,因此在需要关闭资源占用或者关闭锁的的场景下,要选择with语句
讨论区