今日记录一下一个非常好用的模块:traceback
1 | # -*- coding:utf-8 -*- |
执行后输出如下:
1 | --func1 exception-- |
通过示例,我们发现普通的打印异常只有很少量的信息(通常是异常的value值),这种情况下我们很难定位在哪块代码出的问题,以及如何出现这种异常。那么到底要如何打印更加详细的信息呢?下面我们就来一一介绍。
sys.exc_info和traceback object
Python程序的traceback
信息均来源于一个叫做traceback object
的对象,而这个traceback object
通常是通过函数sys.exc_info()
来获取的,先来看一个例子:
1 | # -*- coding:utf-8 -*- |
执行输出后如下:
1 | --func1 exception-- |
通过以上示例我们可以看出,sys.exc_info()
获取了当前处理的exception
的相关信息,并返回一个元组,元组的第一个数据是异常的类型(示例是NameErro
r类型),第二个返回值是异常的value
值,第三个就是我们要的traceback object
.
有了traceback object
我们就可以通过traceback module
来打印和格式化traceback
的相关信息,下面我们就来看下traceback module
的相关函数。
traceback module
Python的traceback module
提供一整套接口用于提取,格式化和打印Python程序的stack traces
信息,下面我们通过例子来详细了解下这些接口:
print_tb
1 | # -*- coding:utf-8 -*- |
输出结果:
1 | File "test_python.py", line 13, in main |
这里我们可以发现打印的异常信息更加详细了,下面我们了解下print_tb
的详细信息:
1 | def print_tb(tb, limit=None, file=None): |
tb
: 这个就是traceback object
, 是我们通过sys.exc_info
获取到的limit
: 这个是限制stack trace
层级的,如果不设或者为None,就会打印所有层级的stack trace
file
: 这个是设置打印的输出流的,可以为文件,也可以是stdout
之类的file-like object
。如果不设或为None,则输出到sys.stderr
。
print_exception
1 | # -*- coding:utf-8 -*- |
输出结果:
1 | Traceback (most recent call last): |
看下print_exception
的源码:
1 | def print_exception(etype, value, tb, limit=None, file=None, chain=True): |
- 跟
print_tb
相比多了两个参数etype
和value
,分别是exception type
和exception value
,加上tb(traceback object)
,正好是sys.exc_info()
返回的三个值 - 另外,与
print_tb
相比,打印信息多了开头的”Traceback (most…)”信息以及最后一行的异常类型和value
信息 - 还有一个不同是当异常为
SyntaxError
时,会有”^”来指示语法错误的位置
print_exc
print_exc
是简化版的print_exception
, 由于exception type
, value
和traceback object
都可以通过sys.exc_info()
获取,因此print_exc()
就自动执行exc_info()
来帮助获取这三个参数了,也因此这个函数是我们的程序中最常用的,因为它足够简单
1 | # -*- coding:utf-8 -*- |
输出结果:
1 | Traceback (most recent call last): |
(由于limit=1,因此只有一个层级被打印出来)
print_exc
的源码:
1 | def print_exc(limit=None, file=None, chain=True): |
- 函数内部直接调用了
peint_exception
format_exc
1 | # -*- coding:utf-8 -*- |
从这个例子可以看出有时候我们想得到的是一个字符串,比如我们想通过logger
将异常记录在log
里,这个时候就需要format_exc
了,这个也是最常用的一个函数,它跟print_exc
用法大致相同,只是不直接打印而是返回了字符串。
format_exc
的源码:
1 | def format_exc(limit=None, chain=True): |
format_exc
参数不支持输出到文件或者标准输出 只会返回一个字符串
traceback module
中还有一些其它的函数,但因为并不常用,就不在展开来讲,感兴趣的同学可以看下参考链接中的文档。
推荐使用loguru
记录异常信息 这个库能够更简洁的方式记录一些栈信息
参考文章: