python中traceback获取异常信息

在日常工作中,我们常常会碰到异常,我们想在异常发生的时候,不但能显示异常发生的位置,还能看到异常方法被调用的堆栈信息,在python中怎么实现呢?
实际上python提供了一个traceback来实现类似功能,这个模块提供了一个标准接口来提取、格式化和打印Python程序的堆栈跟踪。它完全模仿Python解释器打印堆栈跟踪时的行为。当您希望在程序控制下打印堆栈跟踪时,这非常有用。

那这个traceback对象怎么来,在异常的情况下我们怎么获取堆栈信息呢,下面我们举一个例子

# -*- 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)

输出如下:

*** 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 \n    lumberjack()\n', '  File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 17, in lumberjack\n    bright_side_of_life()\n', '  File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 21, in bright_side_of_life\n    return tuple()[0]\n', 'IndexError: tuple index out of range\n']
*** 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 \n    lumberjack()\n', '  File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 17, in lumberjack\n    bright_side_of_life()\n', '  File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 21, in bright_side_of_life\n    return tuple()[0]\n']
*** tb_lineno: 26

我们来解读一个程序,这个程序很简单 ,在lumberjack()方法里调用了bright_side_of_life()方法,bright_side_of_life里面有个空元组,并索引元组的第一个元素,由于是空元组,索引肯定会报错的,所以 程序就跳到了异常处理 except里面(实际上我们也主要是讲怎么获取异常信息的)。
第一句

exc_type, exc_value, exc_traceback = sys.exc_info()

通过系统的exc_info方法获取了exc_type, exc_value, exc_tracebac(分别对应异常类型、异常值、堆栈信息对象),有了这三个值之后我们就能通过trackback这个模块来输出异常信息了。

traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)

这个方法就是打印堆栈信息的,limit参数是打印堆栈信息的深度,如果是None就是全部打印,在这个例子中输出的结果为(这里只输出了一层,因为我们limit=1)

*** print_tb:
  File "D:/WorkSheet/PyhonWorkSheet/demo/traceback_test.py", line 26, in <module>
    lumberjack()

光打印堆栈信息好像还少点什么,比如我还想知道什么类型的异常,有没有打印更全面的,有

traceback.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(语法错误),它打印语法错误所在的行发生时,下一行上有一个插入符号表示近似错误的位置。
例子中输出的结果为

*** 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的简便版,输出的信息是一样的。

我现在不想输出到控制台上,我想以字符串的形式收集然后记录在日志里面,有没有以字符串形式返回这些信息的,是有的

 formatted_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实战,python,开发语言)