文章目录
1 异常简介
参考文章:
Python异常和错误 来源:csdn
Python异常处理(基础详解) 来源:csdn
-
异常: 异常即一个事件,该事件会在程序过程中发生,影响程序的正常执行
-
异常处理: 对于未正确执行的事件,代码会直接终止,从而促使程序员对异常进行处理
-
出现异常的原因: 执行过程中出现问题导致程序无法执行
- 程序遇到逻辑或算法问题
- 运行过程中计算机错误(内存不够或者IO错误)
-
异常处理的步骤:
- 异常产生,检查到错误且解释器认为是异常,并抛出异常
- 异常处理,截获异常,忽略或终止程序处理异常
-
错误: 错误指在程序执行前出现语法或者逻辑问题而导致程序无法被执行
-
出现错误的原因:
- 出现语法错误
- 出现逻辑错误,如:2/0,0是不能作为被除数的,程序写的语法可能没问题,但是逻辑上存在问题
2 异常的传播
- 异常传播概念: 当函数中出现异常时,如果在函数中异常进行了处理,则异常不会进行传播。如果函数中没有对异常进行处理,则异常会继续向函数调用处传播。当传播到全局作用域(主模块)时,若依然没有处理,则程序会终止,并显示异常信息。
- 当程序运行过程中程序异常,所有异常信息会保存到一个异常对象中,而异常传播时,实际上就是异常对象抛给了调用处
3 捕获异常
参考文章:
Python异常及处理方法总结
3.1 捕获异常: try…except
1 捕获异常,不存储异常信息
try:
可能出错的代码块
except name:
如果异常发生,其处理方法块,name为异常类型名
------------------------------------------------
2 捕获异常,存储异常信息
try:
可能出错的代码块
except name as 新名字:
异常发生处理方法块,name为异常类型名
3.2 捕获多个异常
一、捕获多个异常,不存储异常信息
方法1
try:
可能出错代码块
except (异常类型1,异常类型2...)
异常发生处理方法块
----------------------------------------------
方法2
try :
可能出现的语句块
except 异常类型1:
处理方法块
except 异常类型2:
处理方法块
.................
----------------------------------------------
二、捕获多个异常,存储异常信息
方法1
try:
可能出错代码块
except (异常类型1,异常类型二) as result:
print('异常为',result)
----------------------------------------------------
方法2
try :
可能出现的语句块
except 异常类型1 as result1 :
处理方法块
except 异常类型2 as result2 :
处理方法块
.................
注:
在捕获多个异常程序块中,方法二都具有优先级:
- 执行try下的语句块,若发生异常则执行第一个except
- 如果第一个except中定义的异常与引发的异常匹配,则执行该except中的语句
- 如果引发的异常不匹配第一个except,则会搜索第二个except,允许编写的except数量没有限制
- 如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中
3.3 异常中的else
- 功能: 当try语句块中没有错误时,则执行else语句块中的程序
try :
可能出现的语句块
except 异常类型1 :
处理方法块
except 异常类型2 as result2 :
处理方法块
else:
没有捕获到异常而执行的程序
3.3 异常中的finally
功能: 无论是否抛出异常都执行的语句块
用法一:
try:
可能出错的语句块
finally:
无论是否抛出异常都执行的代码块
-------------------------------------
用法二:
try:
可能出错的代码块
except name:
如果异常发生,其处理方法块,name为异常类型名
finally:
无论是否抛出异常都执行的代码块
---------------------------------
用法三:
try :
可能出现的语句块
except 异常类型1 :
处理方法块
except 异常类型2 as result2 :
处理方法块
else:
没有捕获到异常而执行的程序
finally:
无论是否抛出异常都执行的代码块
3.4 异常套嵌与传递
#示例一 内层代码块处理了异常,外层代码正常执行
class yc:
a=4
def test1(self):
try:
print(a)
except Exception as re1:
print('test1发生错误:',re1)
else:
print('test1没有错误')
def test2(self):
try:
print('这是测试2')
self.test1()
except BaseException as re2:
print('test2发生错误:',re2)
else:
print('test2没有错误')
x=yc()
x.test1()
print('-----------------------------')
x.test2()
'''
运行结果:
test1发生错误: name 'a' is not defined
-----------------------------
这是测试2
test1发生错误: name 'a' is not defined
test2没有错误
'''
#----------------------------------------------------------
#示例二 内层代码没有处理异常,传递到外层代码处理
class yc:
a=4
def test1(self):
print(a)
def test2(self):
try:
print('这是测试2')
self.test1()
print('测试一发生错误,抛出异常,这里直接跳过')
except BaseException as re2:
print('test2发生错误:',re2)
else:
print('test2没有错误')
x=yc()
x.test2()
'''
运行结果:
这是测试2
test2发生错误: name 'a' is not defined
'''
- 注:
- 在套嵌中,若内层代码块发生异常并处理了异常,则外层代码块依然正确执行
- 若内层代码块没有处理异常,则将异常抛出给外层代码块处理
- 若有多层代码块,则从内到外层依此抛出,直到处理完成,若最外层依旧没有对异常进行处理,则代码报错
3.5 主动触发异常raise
- 功能:主动引发一个异常
raise [Exception [, args [, traceback]]]
语句中Exception是异常的类型(例如ValueError),参数是一个异常参数值。该参数是可选的,如果不提供,异常的参数是"None"。最后一个参数是跟踪异常对象,也是可选的
3.6 自定义异常
- 原理:通过直接或者间接的方式继承Exception类,创建用户自定义异常
class aError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
class yc:
a=4
def test1(self):
raise aError("这是一个错误")
def test2(self):
try:
print('这是测试2')
self.test1()
print('测试一发生错误,抛出异常,这里直接跳过')
except BaseException as re2:
print('test2发生错误:',re2)
else:
print('test2没有错误')
x=yc()
x.test2()
'''
运行结果:
这是测试2
test2发生错误: 这是一个错误
'''
3.6 traceback模块查看异常
原文链接:
Python异常及处理方法总结
- 原理: 发生异常时,Python能“记住”引发的异常以及程序的当前状态。Python还维护着traceback(跟踪)对象,其中含有异常发生时与函数调用堆栈有关的信息。记住,异常可能在一系列嵌套较深的函数调用中引发。程序调用每个函数时,Python会在“函数调用堆栈”的起始处插入函数名。一旦异常被引发,Python会搜索一个相应的异常处理程序。如果当前函数中没有异常处理程序,当前函数会终止执行,Python会搜索当前函数的调用函数,并以此类推,直到发现匹配的异常处理程序,或者Python抵达主程序为止。这一查找合适的异常处理程序的过程就称为“堆栈辗转开解”(StackUnwinding)。解释器一方面维护着与放置堆栈中的函数有关的信息,另一方面也维护着与已从堆栈中“辗转开解”的函数有关的信息。
- 用法:
try:
block
except:
traceback.print_exc()
#实例:
import traceback
try:
1 / 0
except Exception as e:
print(e)
traceback.print_exc() #若没有此语句,则只会输出“division by zero”,不会显示出错行
'''
运行结果:
File "D:/eclipse/pyth/pyth/test/异常处理.py", line 135, in <module>
1 / 0
ZeroDivisionError: division by zero
division by zero
'''