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 相关文章推荐
Python中的Matplotlib模块入门教程
Apr 15 Python
python计算方程式根的方法
May 07 Python
Python模拟三级菜单效果
Sep 11 Python
使用Python操作excel文件的实例代码
Oct 15 Python
python读取几个G的csv文件方法
Jan 07 Python
Python中的元组介绍
Jan 28 Python
pandas 选取行和列数据的方法详解
Aug 08 Python
python socket通信编程实现文件上传代码实例
Dec 14 Python
django rest framework使用django-filter用法
Jul 15 Python
django前端页面下拉选择框默认值设置方式
Aug 09 Python
详解torch.Tensor的4种乘法
Sep 03 Python
详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案
Jan 29 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生成缩略图的函数代码(修改版)
2011/01/18 PHP
PHP可逆加密/解密函数分享
2012/09/25 PHP
PHP目录操作实例总结
2016/09/27 PHP
PHP7扩展开发之hello word实现方法详解
2018/01/15 PHP
怎么让脚本或里面的函数在所有图片都载入完毕的时候执行
2006/10/17 Javascript
由Javascript实现的页面日历
2011/11/04 Javascript
js数组与字符串的相互转换方法
2014/07/09 Javascript
微信小程序 使用picker封装省市区三级联动实例代码
2016/10/28 Javascript
最常见的左侧分类菜单栏jQuery实现代码
2016/11/28 Javascript
深入理解jquery的$.extend()、$.fn和$.fn.extend()
2017/07/08 jQuery
AngularJS实现自定义指令及指令配置项的方法
2017/11/20 Javascript
微信小程序如何获取用户手机号
2018/01/26 Javascript
Django模板继承 extend标签实例代码详解
2019/05/16 Javascript
jquery实现Ajax请求的几种常见方式总结
2019/05/28 jQuery
taro小程序添加骨架屏的实现代码
2019/11/15 Javascript
微信小程序开发搜索功能实现(前端+后端+数据库)
2020/03/04 Javascript
vue + el-form 实现的多层循环表单验证
2020/11/25 Vue.js
[13:39]2014 DOTA2华西杯精英邀请赛 5 25 NewBee VS DK第一场
2014/05/26 DOTA
[01:07:19]2018DOTA2亚洲邀请赛 4.5 淘汰赛 Mineski vs VG 第一场
2018/04/06 DOTA
python3.7实现云之讯、聚合短信平台的短信发送功能
2019/09/26 Python
15个应该掌握的Jupyter Notebook使用技巧(小结)
2020/09/23 Python
image-set实现Retina屏幕下图片显示详细介绍
2012/12/24 HTML / CSS
amazeui时间组件的实现示例
2020/08/18 HTML / CSS
Rodd & Gunn澳大利亚官网:新西兰男装品牌
2018/09/25 全球购物
巴西备受欢迎的服装和生活方式品牌:FARM Rio
2020/02/04 全球购物
宏碁西班牙官网:Acer西班牙
2021/01/08 全球购物
.TTL是什么?有什么用处,通常那些工具会用到它?(ping? traceroute? ifconfig? netstat?)
2016/05/09 面试题
Linux内核的同步机制是什么?主要有哪几种内核锁
2013/01/03 面试题
中英双版中文教师求职信
2013/10/27 职场文书
县政府办公室领导班子个人对照检查材料
2014/09/16 职场文书
上班迟到检讨书300字
2014/10/18 职场文书
2015年推广普通话演讲稿
2015/03/20 职场文书
公司奖励通知
2015/04/21 职场文书
河童之夏观后感
2015/06/11 职场文书
Java中PriorityQueue实现最小堆和最大堆的用法
2021/06/27 Java/Android
win10怎么设置右下角图标不折叠?Win10设置右下角图标不折叠的方法
2022/07/15 数码科技