12.Python3 异常处理机制
Python3 异常处理机制
1.语法错误和异常
Python 有两种错误很容易辨认:语法错误和异常。
语法错误
语法错误,也就是解析代码时出现的错误。当代码不符合 Python 语法规则时,Python解释器在解析时就会报出 SyntaxError 语法错误,与此同时还会明确指出最早探测到错误的语句。例如:
>>> while True print('Hello world')
File "<stdin>", line 1, in ?
while True print('Hello world')
^
SyntaxError: invalid syntax
函数 print() 被检查到有错误,是它前面缺少了一个冒号 : 。语法分析器指出了出错的一行,并且在最先找到的错误的位置标记了一个小小的箭头。
异常
即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。
大多数的异常都不会被程序处理,以下运行输出结果中,前两段指明了错误的位置,最后一句表示出错的类型。:
>>> 10 * (1/0) # 0 不能作为除数,触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3 # spam 未定义,触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2 # int 不能与 str 相加,触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
2.捕捉异常try/except语句
try/except语句块其基本语法结构如下所示:
try:
执行代码
except [ (Error1, Error2, ... ) [as e] ]:
处理异常的代码块1
except [ (Error3, Error4, ... ) [as e] ]:
处理异常的代码块2
except [Exception]:
处理其它异常
else:
没有异常时执行的代码
finally:
不管有没有异常都会执行的代码
该格式中,[] 括起来的部分可以使用,也可以省略。其中各部分的含义如下:
- (Error1, Error2,...) 、(Error3, Error4,...)都是具体的异常类型。一个 except 块可以同时处理多种异常。
- [as e]:作为可选参数,表示给异常类型起一个别名 e,这样做的好处是方便在 except 块中调用异常类型。
- [Exception]:作为可选参数,可以代指程序可能发生的所有异常情况,其通常用在最后一个 except 块。
- else 和 finally 为可选子句,如果使用这个子句,那么必须放在所有的 except 子句之后。
- finally 为可选子句,如果使用这个子句,那么必须放在 except 和 else子句之后。
- finally 只要求和 try 搭配使用,而至于该结构中是否包含 except 以及 else,对于 finally 不是必须的(else 必须和 try except 搭配使用)。
3.抛出异常raise语句
Python 使用 raise 语句抛出一个指定的异常。
raise语法格式如下:
raise [exceptionName [(reason)]]
其中,用 [] 括起来的为可选参数,其作用是指定抛出的异常名称,以及异常信息的相关描述。如果可选参数全部省略,则 raise 会把当前错误原样抛出;如果仅省略 (reason),则在抛出异常时,将不附带任何的异常描述信息。
也就是说,raise 语句有如下三种常用的用法:
- raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常(在已经引发异常的程序中会再引发一次,在没有异常的程序中引发RuntimeError 异常)。
- raise 异常类名称:raise 后带一个异常类名称,表示引发执行类型的异常。
- raise 异常类名称(描述信息):在引发指定类型的异常的同时,附带异常的描述信息。
4.获取异常信息
捕获异常时,有 2 种方式可获得更多的异常信息,分别是:
- 使用 sys 模块中的 exc_info 方法;
- 使用 traceback 模块中的相关函数。
sys.exc_info()方法
模块 sys 中,有两个方法可以返回异常的全部信息,分别是 exc_info() 和 last_traceback(),这两个函数有相同的功能和用法。
exc_info() 方法会将当前的异常信息以元组的形式返回,该元组中包含 3 个元素,分别为 type、value 和 traceback,它们的含义分别是:
- type:异常类型的名称,它是 BaseException 的子类。
- value:捕获到的异常实例。
- traceback:是一个 traceback 对象。
要查看 traceback 对象包含的内容,需要先引进 traceback 模块,然后调用 traceback 模块中的 print_tb 方法,并将 sys.exc_info() 输出的 traceback 对象作为参数参入。例如:
#使用 sys 模块之前,需使用 import 引入
import sys
#引入traceback模块
import traceback
try:
x = int(input("请输入一个被除数:"))
print("30除以",x,"等于",30/x)
except:
print(sys.exc_info())
traceback.print_tb(sys.exc_info()[2])
print("其他异常...")
traceback模块
traceback模块可以用来查看异常的传播轨迹,追踪异常触发的源头
下面示例显示了如何显示异常传播轨迹:
class SelfException(Exception):
pass
def main():
firstMethod()
def firstMethod():
secondMethod()
def secondMethod():
thirdMethod()
def thirdMethod():
raise SelfException("自定义异常信息")
main()
上面程序中 main() 函数调用 firstMethod(),firstMethod() 调用 secondMethod(),secondMethod() 调用 thirdMethod(),thirdMethod() 直接引发一个 SelfException 异常。运行上面程序,将会看到如下所示的结果:
Traceback (most recent call last):
File "C:\Users\mengma\Desktop\1.py", line 11, in <module>
main()
File "C:\Users\mengma\Desktop\1.py", line 4, in main <--mian函数
firstMethod()
File "C:\Users\mengma\Desktop\1.py", line 6, in firstMethod <--第三个
secondMethod()
File "C:\Users\mengma\Desktop\1.py", line 8, in secondMethod <--第二个
thirdMethod()
File "C:\Users\mengma\Desktop\1.py", line 10, in thirdMethod <--异常源头
raise SelfException("自定义异常信息")
SelfException: 自定义异常信息
从输出结果可以看出,异常从 thirdMethod() 函数开始触发,传到 secondMethod() 函数,再传到 firstMethod() 函数,最后传到 main() 函数,在 main() 函数止,这个过程就是整个异常的传播轨迹。
使用 traceback 模块查看异常传播轨迹,首先需要将 traceback 模块引入,该模块提供了如下两个常用方法:
- traceback.print_exc():将异常传播轨迹信息输出到控制台或指定文件中。
- format_exc():将异常传播轨迹信息转换成字符串。
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器