with语句常用来处理一些事务的事先处理与事后清理工作。像文件处理时要先取得文件句柄,处理完后要关闭文件句柄
file = open('tes.txt')
data = file.read()
file.close()
这里没有对读取数据发生的异常作任何处理,而且容易忘记把文件close掉。下面代码添加异常处理
try:
file = open('tes.txt')
except:
print('fail to open')
try:
data = file.read()
# do something
except:
print('read err')
# do something
finally:
file.close()
这段代码虽然运行良好,但是太冗长了。下面使用with优雅地实现文件操作
with open('tes.txt') as file:
data = file.read()
# do something
这里with会自动处理文件关闭操作。这里没有对打开文件异常作处理,数据读取异的处理是文件对象中定义的,因为是C写的模块,不知道实际处理情况。实际使用时候用try except外层处理一次应该就够了
自定义with处理对象
定义一个对象并实现enter()与exit()方法,分别进行预处理与后处理。enter()返回一个任意对象给as使用
class Tes:
def __enter__(self):
print('in enter')
# raise ValueError('enter error') # 这里的异常会直接退出,不会执行with block与__exit__()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('in exit')
print(exc_type)
print(exc_val)
print(exc_tb)
if exc_type is ValueError:
return True #返回ture时 with block的ValueError异常会被拦截, 程序会正常执行
# 这个不是必需的
def dosomething(self):
print('do something')
with Tes() as t:
t.dosomething()
raise ValueError('block error')
## 运行结果
# in enter
# do something
# in exit
# <class 'ValueError'>
# block error
# <traceback object at 0x102a255c8>
with多个对象
with open('1.txt') as f1, open('2.txt') as f2:
# do something with f1, f2