Python基于traceback模块获取异常信息


Posted in Python onJuly 23, 2020

除了使用 sys.exc_info() 方法获取更多的异常信息之外,还可以使用 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() 函数止,这个过程就是整个异常的传播轨迹。

在实际应用程序的开发中,大多数复杂操作都会被分解成一系列函数或方法调用。这是因为,为了具有更好的可重用性,会将每个可重用的代码单元定义成函数或方法,将复杂任务逐渐分解为更易管理的小型子任务。由于一个大的业务功能需要由多个函数或方法来共同实现,在最终编程模型中,很多对象将通过一系列函数或方法调用来实现通信,执行任务。

所以,当应用程序运行时,经常会发生一系列函数或方法调用,从而形成“函数调用战”。异常的传播则相反,只要异常没有被完全捕获(包括异常没有被捕获,或者异常被处理后重新引发了新异常),异常就从发生异常的函数或方法逐渐向外传播,首先传给该函数或方法的调用者,该函数或方法的调用者再传给其调用者,直至最后传到 Python 解释器,此时 Python 解释器会中止该程序,并打印异常的传播轨迹信息。

很多初学者一看到输出结果所示的异常提示信息,就会惊慌失措,他们以为程序出现了很多严重的错误,其实只有一个错误,系统提示那么多行信息,只不过是显示异常依次触发的轨迹。

其实,上面程序的运算结果显示的异常传播轨迹信息非常清晰,它记录了应用程序中执行停止的各个点。最后一行信息详细显示了异常的类型和异常的详细消息。从这一行向上,逐个记录了异常发生源头、异常依次传播所经过的轨迹,并标明异常发生在哪个文件、哪一行、哪个函数处。

使用 traceback 模块查看异常传播轨迹,首先需要将 traceback 模块引入,该模块提供了如下两个常用方法:

  • traceback.print_exc():将异常传播轨迹信息输出到控制台或指定文件中。
  • format_exc():将异常传播轨迹信息转换成字符串。

可能有读者好奇,从上面方法看不出它们到底处理哪个异常的传播轨迹信息。实际上我们常用的 print_exc() 是 print_exc([limit[, file]]) 省略了 limit、file 两个参数的形式。而 print_exc([limit[, file]]) 的完整形式是 print_exception(etype, value, tb[,limit[, file]]),在完整形式中,前面三个参数用于分别指定异常的如下信息:

  • etype:指定异常类型;
  • value:指定异常值;
  • tb:指定异常的traceback 信息;

当程序处于 except 块中时,该 except 块所捕获的异常信息可通过 sys 对象来获取,其中 sys.exc_type、sys.exc_value、sys.exc_traceback 就代表当前 except 块内的异常类型、异常值和异常传播轨迹。

简单来说, print_exc([limit[, file]]) 相当于如下形式:

print_exception(sys.exc_etype, sys.exc_value, sys.exc_tb[, limit[, file]])

也就是说,使用 print_exc([limit[, file]]) 会自动处理当前 except 块所捕获的异常。该方法还涉及两个参数:

limit:用于限制显示异常传播的层数,比如函数 A 调用函数 B,函数 B 发生了异常,如果指定 limit=1,则只显示函数 A 里面发生的异常。如果不设置 limit 参数,则默认全部显示。
file:指定将异常传播轨迹信息输出到指定文件中。如果不指定该参数,则默认输出到控制台。

借助于 traceback 模块的帮助,我们可以使用 except 块捕获异常,并在其中打印异常传播信息,包括把它输出到文件中。例如如下程序:

# 导入trackback模块
import traceback
class SelfException(Exception): pass
def main():
  firstMethod()
def firstMethod():
  secondMethod()
def secondMethod():
  thirdMethod()
def thirdMethod():
  raise SelfException("自定义异常信息")
try:
  main()
except:
  # 捕捉异常,并将异常传播信息输出控制台
  traceback.print_exc()
  # 捕捉异常,并将异常传播信息输出指定文件中
  traceback.print_exc(file=open('log.txt', 'a'))

上面程序第一行先导入了 traceback 模块,接下来程序使用 except 捕获程序的异常,并使用 traceback 的 print_exc() 方法输出异常传播信息,分别将它输出到控制台和指定文件中。

运行上面程序,同样可以看到在控制台输出异常传播信息,而且在程序目录下生成了一个 log.txt 文件,该文件中同样记录了异常传播信息。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
win7安装python生成随机数代码分享
Dec 27 Python
Python 功能和特点(新手必学)
Dec 30 Python
Python实现的快速排序算法详解
Aug 01 Python
python学习教程之使用py2exe打包
Sep 24 Python
python实现TF-IDF算法解析
Jan 02 Python
纯用NumPy实现神经网络的示例代码
Oct 24 Python
pycharm运行和调试不显示结果的解决方法
Nov 30 Python
使用pytorch和torchtext进行文本分类的实例
Jan 08 Python
详解Python中的编码问题(encoding与decode、str与bytes)
Sep 30 Python
Python Process创建进程的2种方法详解
Jan 25 Python
python - timeit 时间模块
Apr 06 Python
OpenCV-Python实现图像平滑处理操作
Jun 08 Python
Python TestSuite生成测试报告过程解析
Jul 23 #Python
快速解释如何使用pandas的inplace参数的使用
Jul 23 #Python
Python分类测试代码实例汇总
Jul 23 #Python
基于Python3读写INI配置文件过程解析
Jul 23 #Python
Linux安装Python3如何和系统自带的Python2并存
Jul 23 #Python
Java爬虫技术框架之Heritrix框架详解
Jul 22 #Python
Python 绘制可视化折线图
Jul 22 #Python
You might like
几种有用的变型 PHP中循环语句的用法介绍
2012/01/30 PHP
nginx+thinkphp下解决不支持pathinfo模式
2015/07/01 PHP
php用正则判断是否为数字的方法
2016/03/25 PHP
Netbeans 8.2将支持PHP7 更精彩
2016/06/13 PHP
PHP使用curl函数发送Post请求的注意事项
2016/11/26 PHP
WHOOPS PHP调试库的使用
2017/09/29 PHP
YII2框架中ActiveDataProvider与GridView的配合使用操作示例
2020/03/18 PHP
javascript Ext JS 状态默认存储时间
2009/02/15 Javascript
jquery实现人性化的有选择性禁用鼠标右键
2014/06/30 Javascript
浅谈JavaScript Math和Number对象
2015/01/26 Javascript
JavaScript对象反射用法实例
2015/04/17 Javascript
js对象浅拷贝和深拷贝详解
2016/09/05 Javascript
详解angular中通过$location获取路径(参数)的写法
2017/03/21 Javascript
Javascript操作dom对象之select全面解析
2017/04/24 Javascript
Vue结合Video.js播放m3u8视频流的方法示例
2018/05/04 Javascript
vue .js绑定checkbox并获取、改变选中状态的实例
2018/08/24 Javascript
Vue 组件参数校验与非props特性的方法
2019/02/12 Javascript
VScode格式化ESlint方法(最全最好用方法)
2019/09/10 Javascript
Vue 解决路由过渡动画抖动问题(实例详解)
2020/01/05 Javascript
javascript将扁平的数据转为树形结构的高效率算法
2020/02/27 Javascript
前端vue如何使用高德地图
2020/11/05 Javascript
浅谈Python中copy()方法的使用
2015/05/21 Python
python3设计模式之简单工厂模式
2017/10/17 Python
mac下给python3安装requests库和scrapy库的实例
2018/06/13 Python
python模拟登陆,用session维持回话的实例
2018/12/27 Python
python闭包与引用以及需要注意的陷阱
2020/09/18 Python
CSS3制作漂亮的照片墙的实现代码
2016/06/08 HTML / CSS
整理HTML5中表单的常用属性及新属性
2016/02/19 HTML / CSS
介绍一下Ruby的多线程处理
2013/02/01 面试题
2014年初中班主任工作总结
2014/11/08 职场文书
店铺转让协议书
2014/12/02 职场文书
物业项目经理岗位职责
2015/04/01 职场文书
2015年母亲节活动策划方案
2015/05/04 职场文书
校车司机安全责任书
2015/05/11 职场文书
Java 通过手写分布式雪花SnowFlake生成ID方法详解
2022/04/07 Java/Android
Golang 实现 WebSockets 之创建 WebSockets
2022/04/24 Golang