在日常工作中,我们常常会碰到异常,我们想在异常发生的时候,不但能显示异常发生的位置,还能看到异常方法被调用的堆栈信息,在python中怎么实现呢?
实际上python提供了一个traceback来实现类似功能,这个模块提供了一个标准接口来提取、格式化和打印Python程序的堆栈跟踪。它完全模仿Python解释器打印堆栈跟踪时的行为。当您希望在程序控制下打印堆栈跟踪时,这非常有用。
那这个traceback对象怎么来,在异常的情况下我们怎么获取堆栈信息呢,下面我们举一个例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29# -*- coding: utf-8 -*- import traceback, sys def lumberjack(): bright_side_of_life() def bright_side_of_life(): return tuple()[0] if __name__ == '__main__': try: lumberjack() except IndexError: exc_type, exc_value, exc_traceback = sys.exc_info() print("*** print_tb:") traceback.print_tb(exc_traceback, limit=1, file=sys.stdout) print("*** print_exception:") traceback.print_exception(exc_type, exc_value,exc_traceback, limit=2, file=sys.stdout) print("*** print_exc:") traceback.print_exc(limit=2, file=sys.stdout) print("*** format_exc, first and last line:") formatted_lines = traceback.format_exc().splitlines() print(formatted_lines[0]) print(formatted_lines[-1]) print("*** format_exception:") print(repr(traceback.format_exception(exc_type, exc_value,exc_traceback))) print("*** extract_tb:") print(repr(traceback.extract_tb(exc_traceback))) print("*** format_tb:") print(repr(traceback.format_tb(exc_traceback))) print("*** tb_lineno:", exc_traceback.tb_lineno)
输出如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40*** print_tb: File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 26, in <module> lumberjack() *** print_exception: Traceback (most recent call last): File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 26, in <module> lumberjack() File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 17, in lumberjack bright_side_of_life() IndexError: tuple index out of range *** print_exc: Traceback (most recent call last): File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 26, in <module> lumberjack() File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 17, in lumberjack bright_side_of_life() IndexError: tuple index out of range *** format_exc, first and last line: Traceback (most recent call last): IndexError: tuple index out of range *** format_exception: ['Traceback (most recent call last):n', ' File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 26, in <module>n lumberjack()n', ' File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 17, in lumberjackn bright_side_of_life()n', ' File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 21, in bright_side_of_lifen return tuple()[0]n', 'IndexError: tuple index out of rangen'] *** extract_tb: [<FrameSummary file D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py, line 26 in <module>>, <FrameSummary file D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py, line 17 in lumberjack>, <FrameSummary file D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py, line 21 in bright_side_of_life>] *** format_tb: [' File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 26, in <module>n lumberjack()n', ' File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 17, in lumberjackn bright_side_of_life()n', ' File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 21, in bright_side_of_lifen return tuple()[0]n'] *** tb_lineno: 26
我们来解读一个程序,这个程序很简单 ,在lumberjack()方法里调用了bright_side_of_life()方法,bright_side_of_life里面有个空元组,并索引元组的第一个元素,由于是空元组,索引肯定会报错的,所以 程序就跳到了异常处理 except里面(实际上我们也主要是讲怎么获取异常信息的)。
第一句
1
2exc_type, exc_value, exc_traceback = sys.exc_info()
通过系统的exc_info方法获取了exc_type, exc_value, exc_tracebac(分别对应异常类型、异常值、堆栈信息对象),有了这三个值之后我们就能通过trackback这个模块来输出异常信息了。
1
2traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
这个方法就是打印堆栈信息的,limit参数是打印堆栈信息的深度,如果是None就是全部打印,在这个例子中输出的结果为(这里只输出了一层,因为我们limit=1)
1
2
3
4*** print_tb: File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 26, in <module> lumberjack()
光打印堆栈信息好像还少点什么,比如我还想知道什么类型的异常,有没有打印更全面的,有
1
2traceback.print_exception(exc_type, exc_value,exc_traceback, limit=2, file=sys.stdout)
它与print_tb()在以下方面不同:
(1)如果traceback不是None,它打印一个报头“Traceback (most recent call last):”;
(2)输出异常类型和异常值堆栈跟踪;
(3)如果type是SyntaxError(语法错误),它打印语法错误所在的行发生时,下一行上有一个插入符号表示近似错误的位置。
例子中输出的结果为
1
2
3
4
5
6
7
8*** print_exception: Traceback (most recent call last): File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 26, in <module> lumberjack() File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 17, in lumberjack bright_side_of_life() IndexError: tuple index out of range
traceback.print_exception方法还需要传入错误类型、错误值、堆栈跟踪对象等,挺麻烦的,有没有不需要传入这些一些的更简便的方法呢,有的就是traceback.print_exc
traceback.print_exc(limit=2, file=sys.stdout)
其实 它不需要传入上面提到的三个参数,它函数内部自己通过sys.exc_info()获取了,所以 traceback.print_exc是traceback.print_exception的简便版,输出的信息是一样的。
我现在不想输出到控制台上,我想以字符串的形式收集然后记录在日志里面,有没有以字符串形式返回这些信息的,是有的
1
2formatted_lines = traceback.format_exc()
traceback.format_exc()和traceback.print_exc的内容是一样的 只是它返回为字符串,方便你收集。
traceback.format_exc是traceback.format_exception简便版,不需要传入我们上面说的故障类型、故障值、堆栈跟踪对象这三个参数。
traceback.format_tb是traceback.extract_tb返回值的格式化版本,traceback.extract_tb返回一个StackSummary对象来自回溯的预处理条目列表。
最后
以上就是传统小笼包最近收集整理的关于python中traceback获取异常信息的全部内容,更多相关python中traceback获取异常信息内容请搜索靠谱客的其他文章。
发表评论 取消回复