day 34 异常处理
1 什么是异常
-
异常处理的三个特征
异常的追踪信息
异常的类型
异常的内容
异常是程序发生错误的信号。程序一旦出现错误,便会产生一个异常,若程序中没有处理它,就会抛出该异常,程序的运行也随之终止。在Python中,错误触发的异常如下

而错误分成两种,一种是语法上的错误SyntaxError,这种错误应该在程序运行前就修改正确
>>> if
File "<stdin>", line 1
if
^
SyntaxError: invalid syntax
另一类就是逻辑错误,常见的逻辑错误如
# TypeError:数字类型无法与字符串类型相加
1+’2’
# ValueError:当字符串包含有非数字的值时,无法转成int类型
num=input(">>: ") #输入hello
int(num)
# NameError:引用了一个不存在的名字x
x
# IndexError:索引超出列表的限制
l=['egon','aa']
l[3]
# KeyError:引用了一个不存在的key
dic={'name':'egon'}
dic['age']
# AttributeError:引用的属性不存在
class Foo:
pass
Foo.x
# ZeroDivisionError:除数不能为0
1/0
2 为何处理异常
为了增强程序的健壮性,即便是程序运行过程中出错了,也不要终止程序,而是捕捉异常并处理:将出错信息记录到日志内
3 如何处理异常?
为了保证程序的容错性与可靠性,即在遇到错误时有相应的处理机制不会任由程序崩溃掉,我们需要对异常进行处理,处理的基本形式为
3.1 语法上的错误 SyntaxError,
处理方式:必须在程序运行前就改正
if 1>3
print("run...")
3.2 逻辑上的错误
print(x)
>>>>>>>>>>>>>>
l=['a','b']
l[2]
>>>>>>>>>>>>>>
1/0
>>>>>>>>>>>>>>
int('abc')
>>>>>>>>>>>>>>
dic={'name':'egon'}
dic['age']
>>>>>>>>>>>>>>
class Foo:
pass
Foo.x
针对逻辑上的异常又分成两种处理方式
3.2.1 错误发生的条件是可以预知的,使用 if 判断来解决
age=input('>>: ').strip() # 输入的只要不是数字就会出错
if age.isdigit():
age=int(age)
if age > 18:
print('猜大了')
elif age < 18:
print('猜大了')
else:
print('猜对了')
else:
print('必须输入数字')
3.2.2 错误发生的条件是无法预知的
处理的基本形式为
try:
被检测的代码块
except 异常类型:
检测到异常,就执行这个位置的逻辑
print('start...')
try:
#有可能会抛出异常的代码
子代码 1
子代码 2
子代码 3
except 异常类型 1 as e:
pass
except 异常类型 2 as e:
pass
...
else:
#如果被检测的子代码块没有异常发生,则会执行 else 的子代码
finally:
#无论被检测的子代码块有无异常发生,都会执行 finally 的子代码
print('end...')
本来程序一旦出现异常就整体结束掉了,有了异常处理以后,在被检测的代码块出现异常时,被检测的代码块中异常发生位置之后的代码将不会执行,取而代之的是执行匹配异常的except子代码块,其余代码均正常运行。
用法一
基本形式
print('start...')
try:
print('1111111111')
l=['aaa','bbbb']
l[3] # 抛出异常 IndexError,该行代码同级别的后续代码不会运行
print('2222222222')
x
print('33333333')
dic={'a':1}
dic['a']
except IndexError as e:
print('异常的信息: ',e)
print('end....')
用法二
如果我们想分别用不同的逻辑处理,需要用到多分支的except(类似于多分支的elif,从上到下依次匹配,匹配成功一次便不再匹配其他)
print('start...')
try:
print('1111111111')
l=['aaa','bbbb']
# l[3] # 抛出异常 IndexError,该行代码同级别的后续代码不会运行
print('2222222222')
xxx
print('33333333')
dic={'a':1}
dic['a']
except IndexError as e:
print('异常的信息: ',e)
except NameError as e:
print('异常的信息: ',e)
print('end....')
用法三
如果我们想多种类型的异常统一用一种逻辑处理,可以将多个异常放到一个元组内,用一个except匹配。如果我们想捕获所有异常并用一种逻辑处理,Python提供了一个万能异常类型Exception
print('start...')
try:
print('1111111111'
l = ['aaa', 'bbbb']
l[3] # 抛出异常 IndexError,该行代码同级别的后续代码不会运行
print('2222222222')
xxx
print('33333333')
dic = {'a': 1}
dic['aaa']
except (IndexError, NameError) as e:
print('异常的信息: ', e)
except KeyError as e:
print('字典的 key 不存在: ', e)
except Exception as e: # 万能异常
print('所有异常都可以匹配的到')
print('end....')
用法四
else 不能单独与 try 配合使用,必须要搭配 except。在多分支except之后还可以跟一个else(else必须跟在except之后,不能单独存在),只有在被检测的代码块没有触发任何异常的情况下才会执行else的子代码块
print('start...')
try:
print('1111111111')
print('2222222222')
print('33333333')
except Exception as e: # 万能异常
print('所有异常都可以匹配的到')
else:
print('====>')
print('end....')
用法五
finally 可以单独与 try 配合使用。此外try还可以与finally连用,从语法上讲finally必须放到else之后,但可以使用try-except-finally的形式,也可以直接使用try-finally的形式。无论被检测的代码块是否触发异常,都会执行finally的子代码块,因此通常在finally的子代码块做一些回收资源的操作,比如关闭打开的文件、关闭数据库连接等
python try: 被检测的代码块 except 异常类型1: pass except 异常类型2: pass ...... else: 没有异常发生时执行的代码块 finally: 无论有无异常发生都会执行的代码块
print('start...')
try:
print('1111111111')
l = ['aaa', 'bbbb']
l[3] # 抛出异常 IndexError,该行代码同级别的后续代码不会运行
print('2222222222')
xxx
print('33333333')
dic = {'a': 1}
dic['aaa']
finally: # 不处理异常,无论是否发生异常都会执行 finally 的子代码
print('====》》》》》应该把被检测代码中回收系统资源的代码放到这里')
print('end....')

浙公网安备 33010602011771号