在python中会遇到两种错误,一种,是语法错误,这种错误不能被解释器容忍,必须更改为正确语法后程序才能运行;而另外一种,是在程序运行过程中出现的错误,诸如NameError,TypeError等此类错误,有错误名称和行号以及报错内容的错误,称之为异常。
try:
error_statement
except [(ExceptionName1,ExceptionName2 ...) [as ...]]:
do_Excepttion_statement1
except [(ExceptionName1,ExceptionName2 ...) [as ...]]:
do_Excepttion_statement2
except [(...) [as ...]]:
...
else:
nothing_of_Exception_statement
finally:
other_statement
名词解释:
[]:方括号内的内容不必一定出现
try:异常捕获块,有且仅有一个
except:异常处理块,可以有多个,且每个可以同时处理多种异常;不必一定存在
else:在未捕获到异常时,进入else;else可可选的,不必一定存在
finaly:不论try有没有捕获到异常都会进入的块,这里很多同学没有深刻体会到它的用途,只是单纯认为,此关键字不是必须的,没有那么重要,这个是讨论的一点,帮助各位童鞋理解加深印象。
as:为各种异常进行一个起别名额功能。
1、首先执行try中的代码块(error_statement),如果代码执行过程中出现异常,python会立刻生成一个对应的异常对象,并且将该异常上报解释器,由解释器获得异常的过程,称之为异常捕获。
2、如果捕获到异常,会立刻进入异常处理流程(此时在try中异常出现以后的代码不会再运行),即except关键字引导的块,根据关键字后边的ExceptionName来自上而下由左及右地逐个检查是否有对应的异常名称,如果有则进入对应的except模块,执行其中的do_Excepttion_statement代码块;如果没有检测到匹配的异常名称则不会进入任何except块,代码会继续向下运行。
3、else流程:在try中未检测到任何异常才会进入else,童鞋们可能会有疑问?是没有检测到异常,还是except没有包含该异常?注意~~这是两个概念,前者是没有异常,后者是有异常但是没有进行except处理。答案是,没有检测到任何异常(代码完全OK)才会进入else。示例如下:
try:
a = 1
print(a/0) #此处会有ZeroDivisionError异常
except NameError: #处理的except块中未包含ZeroDivisionError异常
print('name is error!')
else:
print('nothing...')
#以上代码会出现:
'''
Traceback (most recent call last):
File "F:/PycharmProjects/class_obj/class_one.py", line 94, in
print(a/0)#此处会有ZeroDivisionError异常
ZeroDivisionError: division by zero
'''
#并不会进入else中
4、except流程:此处主要强调在最上边例子中的except [(ExceptionName1,ExceptionName2 …) [as …]]: 的理解,‘[ ]’上边提到过,是代表可以没有;那么,童鞋写了如下代码,看看两种代码的结果是否相同呢?
#代码一:
try:
a = 1
print(a/0)
except:
print('name is error!')
else:
print('nothing...')
#代码二:
try:
a = 1
print(a/0)
else:
print('nothing...')
首先,需要搞清楚,代码二是有语法错误的,这个必须得改正,问题在于else不能和try搭配,只能和except;第二点,这个是重点,只写except和什么都不写之间有没有区别?答案是肯定的,什么都不写代表不进行处理,而只写 ‘except :’ 相当于 ‘except Exception:’,这种写法意思是说万能异常处理,即Exception这种异常是所有异常的统称,所以如上的代码一是势必会打印‘name is error’这句话。
5、finally流程(*重点) :童鞋们往往在有些时候比较难理解finally的存在的意义,但是对于这样的流程,大家却都知道 ‘无论try是否捕获到异常,都会进入finally流程’;那么接下来,我们细细品一品这个sao气外漏的fianlly究竟为何如此之sao。
5,1 fianlly: 其实这玩意有个冠冕堂皇的功能:垃圾处理机制,说白了,如果你打开了一些物理文件,最终,是需要finally来进行关闭的(有同学就说了,那不写在finally里边不行吗,也可以。)
5,2究竟如何理解?示例如下:
#一切正常如初的‘傻瓜’例子(一个好看的皮囊):
try:
a = 1
print(a/0)
except ZeroDivisionError as e:
print(str(e),#division by zero
repr(e),#ZeroDivisionError('division by zero',)
e.args)#('division by zero',)
finally:
print('final')
#得到结果为:
'''
division by zero ZeroDivisionError('division by zero',) ('division by zero',)
final
'''
#藏身之处(一个龌龊的灵魂):
try:
a = 1
print(a/0)
finally:
print('final')
#和下边代码什么区别呢?
#万恶之源:
try:
a = 1
print(a/0)
print('final')
#有很多初学者认为二者没有结果上的区别,但是,世事难料:
#藏身之处:
'''
Traceback (most recent call last):
File "F:/PycharmProjects/class_obj/class_one.py", line 94, in
print(a/0)
ZeroDivisionError: division by zero
final
'''
#万恶之源:
'''
哈哈哈,这他妹的就是逗逗你们,这是语法错误!!!!
try之后一定要有except、finally中的任何一个哦。换句严肃点的来说,
藏身之处很神奇哦,仔细想想,为什么报错了还能打印finally中的内容呢?
这就是finally最强大的地方!!!
'''
5.3 总结:
当 try 块中代码发生异常,导致程序崩溃时,在崩溃前 Python 解释器也会执行 finally 块中的代码
四、未完待续。。。