python的with...as相当于整合了try...except的用法,但是比try...except的用法更加简洁
先说一说try...except...finally的用法
try语句中程序先执行try中语句,遇到错误执行excep语句,不过程序如何最后都会输出finally语句
try语句中如果执行多条语句,如果第一条出错误,则会执行except语句中的程序,第一条语句后的程序将不被执行。如下:
try:
print(1 / 0)#只执行这一步
print(b)
print("1")
except ZeroDivisionError:
print("分母为0")
except NameError:
print("未定义自变量")
except:
print("其他错误!")
finally:
print("无论执不执行except语句,都会执行finally语句")
最终结果:
分母为0
无论执不执行except语句,都会执行finally语句
except语句中除了系统的标准异常外,我们还可以自定义异常。
如果要根据不同的标准异常进行不同的处理,需要在except后加上该异常的名字:
except ZeroDivisionError:
print("分母为0")
except NameError:
print("未定义自变量")
with...as语句
try...except可以解决一些不必要的麻烦,但是使用with..as语句更能体现python的简洁优雅。
原理:
with...as语句中,先执行with后面的语句,然后返回一个值给定as后面的变量,再进行as后下一步的程序
示例代码:
class Sample:
def __enter__(self):
print("in __enter__")
return ("Foo")
def __exit__(self, exc_type, exc_val, exc_tb):
print("in __exit__")
def get_sample():
return Sample()
with get_sample() as sample:
print("Sample: ", sample)
输出结果:
in __enter__
Sample: Foo
in __exit__
执行程序如下:
1.先执行了get_sample语句
2.get_sample实例化Sample类,Sample类中先执行__enter__方法,执行print语句后,返回Foo给sample
3.利用返回的值,执行print语句输出sample
4.继续执行Sample中未执行完的语句__exit__方法
分析过程:
可以看出__enter__方法就相当于执行了try语句,执行完try语句执行了as后续的语句,最后执行的__exit__语句相当于finally语句。
这是程序无错的例子,我们再来举一个程序有错的例子
示例代码:
class Sample():
def __enter__(self):
print('in enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("type: ", exc_type)
print("val: ", exc_val)
print("tb: ", exc_tb)
def do_something(self):
bar = 1 / 0
return bar + 10
with Sample() as sample:
sample.do_something()
注意:exit方法中的三个参数:
exc_type: 错误的类型
exc_val: 错误类型对应的值
exc_tb: 代码中错误发生的位置
结果如下:
in enter
type: <class 'ZeroDivisionError'>
val: division by zero
tb:
Traceback (most recent call last):
File "D:/pythonProject/爬虫/try.py", line 13, in <module>
sample.do_something()
File "D:/pythonProject/爬虫/try.py", line 10, in do_something
bar = 1 / 0
ZeroDivisionError: division by zero
执行程序如下:
1.先执行实例化Sample类,并执行__enter__方法,执行print语句,并实例自己返回给sample
2.执行sample.dosomething()语句,此时遇到报错,分母不能为0,退出该语句。
3.接着执行Sample类中的方法,将刚刚错误的值的类型,值,位置输出。
4.接着执行下一个方法dosomething()方法,系统报错。
过程分析:
先执行Sample()类再执行__enter__语句相当于执行try语句,返回值后再执行sample.dosomething()语句,此时仍相当于执行try语句,sample.dosomething()出现错误后停止该方法,返回Sample继续执行剩下的语句,执行__exit__语句相当于执行了except语句,后再执行接下的Sample类中的其他方法相当于执行了finally语句
参考博客:参考1