python疑难问题---7、python中的with...as...
一、总结
一句话总结:
with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。
with open("test.txt") as file: data = file.read() print(data) 等价于 try: file = open("test.txt") data = file.read() print(data) finally: file.close()
1、with...as...语句会捕获异常,会处理异常么?
with...as...语句只会捕获异常,但是不会处理异常
with open("test.txt") as file: data = file.read() print(data) 如果没有test.txt,还是会出现以下错误 FileNotFoundError Traceback (most recent call last) <ipython-input-4-bf5e860f28d5> in <module> 1 try: ----> 2 file = open("test.txt") 3 data = file.read() 4 print(data) 5 # except Exception as err: FileNotFoundError: [Errno 2] No such file or directory: 'test.txt'
二、python中的with...as...
博客对应课程的视频位置:7、python中的with...as...-范仁义-读书编程笔记
https://www.fanrenyi.com/video/32/320
一、With语句是干什么的?
有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。
一个很好的例子是文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。
如果不用with语句,代码如下:
file = open("test.txt")
data = file.read()
print(data)
file.close()
这里有两个问题
-
一是可能忘记关闭文件句柄;
-
二是文件读取数据发生异常,没有进行任何处理。
下面是处理异常的加强版本:
try:
file = open("test.txt")
data = file.read()
print(data)
# except Exception as err:
# print("捕获到异常,异常信息为{}".format(err))
finally:
file.close()
虽然这段代码运行良好,但是太冗长了。
这时候就是with一展身手的时候了。
除了有更优雅的语法,with还可以很好的捕获上下文环境产生的异常(但是并不能处理)。
下面是with版本的代码:
with open("test.txt") as file:
data = file.read()
print(data)
等价于:
try:
file = open("test.txt")
data = file.read()
print(data)
finally:
file.close()
二、with工作原理
with基本思想是with所求值的对象必须有一个enter()方法,一个exit()方法。
下面程序定义了一个 People 类,并包含了 enter() 和 exit() 两个方法,因此该类的对象可以被 with as 语句管理。
class People:
def __enter__(self):
print("In __enter__()")
return "Fry"
def __exit__(self, type, value, trace):
print("In __exit__()")
def get_people():
return People()
with get_people() as people:
print("people:", people)
紧跟with后面的语句被求值后,返回对象的enter()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的exit()方法。
下面例子可以具体说明with如何工作:
正如你看到的,
-
enter()方法被执行
-
enter()方法返回的值 - 这个例子中是"Fry",赋值给变量'people'
-
执行代码块,打印变量"people"的值为 "Fry"
-
exit()方法被调用
with另一个强大之处是它可以捕获异常。
可能你已经注意到People类的exit方法有三个参数- val, type 和 trace。 这些参数在异常处理中相当有用。
我们来改一下代码,看看具体如何工作的。
class Sample:
def __enter__(self):
return self
def __exit__(self, type, value, trace):
print("type:", type)
print("value:", value)
print("trace:", trace)
# trace为None,代表没有异常
# if trace is None:
# print('没有异常时关闭资源')
# else:
# print('遇到异常时关闭资源')
def do_something(self):
bar = 1/0
return bar + 10
with Sample() as sample:
sample.do_something()