Python的异常处理
一、什么是异常
异常时程序发生错误的信号,程序一旦出错就会抛出异常
在pycharm编辑器中直接编辑一个变量名x-->run
x # 定义变量名
异常的三个特征:1、异常的追踪信息。2、异常的类型。3、异常的内容
# 运行结果如下:
Traceback (most recent call last): # 文件的定位信息(1、异常的追踪信息)
File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 5, in <module> # 异常发生在哪行?
x # (3、异常的内容)
NameError: name 'x' is not defined # 异常的种类(2、异常的类型)
# 异常时程序发生错误的信号,程序一旦出错就会抛出异常,程序的运行随即终止,异常后的代码不会运行了
print("异常运行前的代码")
x
print("异常运行后的代码")
运行结果:
异常运行前的代码
Traceback (most recent call last):
File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 6, in <module>
x
NameError: name 'x' is not defined
二、为何处理异常
为了增强程序的健壮性,即便是程序运行过程中出错了,也不要终止程序
而是应该捕捉异常并处理:将出错的信息记录到日志里
三、如何处理异常
3.1、异常的来源
# 1)语法上的错误(SyntaxError)
if 1>3
print("run...")
运行结果:
File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 17
if 1>3
^
SyntaxError: invalid syntax
针对语法错误的处理方式一:必须在程序运行前改正。
# 2)逻辑上的错误 # 逻辑错误示范一 print(x) 运行结果: Traceback (most recent call last): File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 20, in <module> print(x) NameError: name 'x' is not defined # 引用一个不存在的名字x # 逻辑错误示范二 1/0 运行结果: Traceback (most recent call last): File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 21, in <module> 1/0 ZeroDivisionError: division by zero # 除数不能为0 # 逻辑错误示范三 int('abc') 运行结果: Traceback (most recent call last): File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 22, in <module> int('abc') ValueError: invalid literal for int() with base 10: 'abc' # 逻辑错误示范四 dic = {'name':'lsj'} dic['name'] 运行结果: Traceback (most recent call last): File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 24, in <module> dic['age'] KeyError: 'age' # 引用了一个不存在的key # 逻辑错误示范五 class Foo: pass Foo.x 运行结果: Traceback (most recent call last): File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 29, in <module> Foo.x AttributeError: type object 'Foo' has no attribute 'x' # 引用的属性不存在
# 逻辑错误示范六:
# TypeError:数字类型无法与字符串类型相加
1+’2’
# 逻辑错误示范七:
# ValueError:当字符串包含有非数字的值时,无法转成int类型
num=input(">>: ") #输入hello
int(num)
# 逻辑错误示范八:
# IndexError:索引超出列表的限制
l=['egon','aa']
l[3]
# 针对逻辑错误的处理方式:有两种
逻辑错误处理方式一
# 方式一:错误发生的方式时可以预知的
# 猜年龄程序为例:
age = input('>>>:').strip()
age = int(age)
if age > 18:
print('猜大了')
elif age < 18:
print('猜小了')
else:
print('猜对了')
# 运行程序时输入数字
# >>>: 18
# 猜对了
# 程序运行时输入其他字符(这样的错误我们可以预知)
# >>>:aaaa
"""
Traceback (most recent call last):
File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 38, in <module>
age = int(age)
ValueError: invalid literal for int() with base 10: 'aaaa'
"""
# 猜年龄程序为例:
age = input('>>>:').strip() # 输入的只要不是数字就会出错,所以在逻辑上进行处理
if age.isdigit(): # 使用if判断解决预知发生的错误
age = int(age)
if age > 18:
print('猜大了')
elif age < 18:
print('猜小了')
else:
print('猜对了')
else:
print("必须输入数字")
# 运行程序时输入数字
# >>>: 18
# 猜对了
# 程序运行时输入其他字符(这样的错误我们可以预知)
# >>>:aaaa
# 必须输入数字
逻辑错误处理方式二
# 方式二:错误发生的方式时无法预知的
"""以C/S架构为例,客户端发送请求,服务端没有接收,导致程序崩溃,我们再使用if判断就无法避免异常了
C<=============>S
"""
# 针对无法预知的异常,我们使用try语法(全部的语法罗列)
print('start...')
try:
# 有可能抛出异常的代码
子代码块1
子代码块2 # 如果此处有错误,同级后续代码不会运行,而是匹配异常类型去
子代码块3 # 此处不能是回收资源的操作,要把回收资源的操作放进finally里,保证资源回收正常运行
except 异常类型1 as e: # as作用是把异常的类型去一个别名给e,我们能可以再后期对这个e进行操作:打印或者记录到日志里。
pass
except 异常类型2 as e:
pass
...
else:
如果被检测的子代码块没有异常发生,则会执行else的子代码
finally:
无论被检测的子代码块有无异常发生,都会执行finally的子代码
print('end...')
# try语法变形一:
try:
子代码块1
子代码块2
子代码块3
except 异常类型1 as e:
pass
# try语法变形二:
try:
子代码块1
子代码块2
子代码块3
finally:
无论被检测的子代码块有无异常发生,都会执行finally的子代码
注意:上面的做法降低了代码的可读性(所以能少用就少用)
# 使用try来演示可预见异常
# 用法一:
print('start...')
try:
print('1111')
l = ['aaa','bbb']
l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
print('2222')
xxx
print('3333')
dic = {'a':1}
dic['a']
except IndexError as e:
# print('异常已经被处理')
print('异常的信息:',e)
print('end...')
运行结果:
start...
1111
异常的信息: list index out of range # 列表索引超出范围
end...
# 注意用法一:使用其他异常代替IndexError异常
print('start...')
try:
print('1111')
l = ['aaa','bbb']
l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
print('2222')
xxx
print('3333')
dic = {'a':1}
dic['a']
# except IndexError as e: # 索引异处理
except ValueError as e: # 如果我们使用ValueError异常接收,由于代码是逐行向下运行,遇到哪个异常就报哪个异常
print('异常的信息:',e)
print('end...')
运行结果:
start...
1111
Traceback (most recent call last):
File "D:/pycharm/oldboy_29/day034/day034_04.py", line 11, in <module>
l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
IndexError: list index out of range
# 用法二 print('start...') try: print('1111') l = ['aaa','bbb'] # l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了 print('2222') xxx print('3333') dic = {'a':1} dic['a'] except IndexError as e: # 索引异处理 print('异常的信息:',e) except NameError as e: print('异常的信息:', e) print('end...')
运行结果
start...
1111
2222
异常的信息: name 'xxx' is not defined
end...
# 这里有个问题就是print('异常的信息:',e)有重复代码的出现
# 用法三:针对多种异常的合并 print('start...') try: print('1111') l = ['aaa','bbb'] # l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了 print('2222') # xxx print('3333') dic = {'a':1} dic['a'] dic['bb'] except (IndexError,NameError) as e: # 以元组形式加入到一行里 print('异常的信息:',e) except KeyError as e: print('字典的key不存在:',e) print('end...')
运行结果:
start...
1111
2222
3333
字典的key不存在: 'bb'
end...
# 用法四:万能异常
print('start...')
try:
print('1111')
l = ['aaa','bbb']
# l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
print('2222')
# xxx
print('3333')
dic = {'a':1}
dic['a']
dic['bb']
# except (IndexError,NameError) as e: # 以元组形式加入到一行里
# print('异常的信息:',e)
# except KeyError as e:
# print('字典的key不存在:',e)
except Exception as e:
print('所有异常都可以匹配的到')
print('end...')
# 用法五:else不能与try配合使用会报语法错误
print('start...')
try:
print('1111')
l = ['aaa','bbb']
# l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
print('2222')
# xxx
print('3333')
dic = {'a':1}
dic['a']
dic['bb']
# except Exception as e:
# print('所有异常都可以匹配的到')
else:
print('===>')
print('end...')
运行结果:
File "D:/pycharm/oldboy_29/day034/day034_05.py", line 17
else:
^
SyntaxError: invalid syntax
# 用法六:try不能与finally配合使用
#
print('start...')
try:
print('1111')
l = ['aaa','bbb']
l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
print('2222')
xxx
print('3333')
dic = {'a':1}
dic['a']
dic['bb']
finally: # finally不处理异常,无论是否发生异常都会执行finally的子代码
print('try与fianlly配合===>此处应该把被检测代码中回收系统资源的代码放到这里')
print('end...')
运行结果:
Traceback (most recent call last):
start...
File "D:/pycharm/oldboy_29/day034/day034_05_01.py", line 8, in <module>
1111
l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
try与fianlly配合
IndexError: list index out of range