Traceback包【持续更新】

Traceback包

简介

traceback 是 Python 标准库中的一个模块,它提供了一组用于提取、格式化和打印程序执行过程中的堆栈跟踪信息的工具。当程序发生异常且未被捕获时,Python 会自动生成一个堆栈跟踪,显示出错的位置和调用栈。这有助于开发者理解和调试程序中出现的问题。

主要功能

当程序发生异常时,traceback模块可以用来捕获和格式化相关的堆栈信息。这有助于开发者快速定位问题所在。格式化的堆栈信息通常包括以下内容:

  • 文件名:显示出现异常的代码所在的文件。
  • 行号:指示引发异常的具体代码行在文件中的位置。
  • 函数名:显示出现异常的代码所在的函数或方法的名称。
  • 代码行:提供引发异常的实际代码行的文本。

traceback模块提供了多种函数来格式化和打印堆栈信息,下面是一些常用的函数:

traceback.print_tb(tb, limit=None, file=None)

  • 打印堆栈跟踪的摘要。tb是一个traceback对象,limit指定打印的堆栈帧数目,file指定输出的文件对象(默认是sys.stderr)。

traceback.print_exception(etype, value, tb, limit=None, file=None, chain=True)

  • 打印异常信息和堆栈跟踪。etype是异常类型,value是异常实例,tb是traceback对象,limit和file的含义与print_tb相同,chain确定是否打印异常链

traceback.format_tb(tb, limit=None)

  • 返回堆栈跟踪的格式化表示,是一个字符串列表,每个字符串代表堆栈中的一个层级

traceback.format_exception(etype, value, tb, limit=None, chain=True)

  • 返回一个列表,其中包含异常信息和堆栈跟踪的格式化字符串

traceback.format_exc(limit=None, chain=True)

  • 返回最近异常的堆栈跟踪的格式化字符串,是format_exception的简化形式。

使用场景

下面有一个多层嵌套的函数调用

def main():
    raise Exception("This is a test")

def pass_func_01():
    return main()

def pass_func_02():
    return pass_func_01()

def pass_func_03():
    return pass_func_02()

def open_func():
    pass_func_03()

if __name__ == "__main__":
    open_func()

>>>
Traceback (most recent call last):
  File "study-test/traceback-test/Demo03.py", line 17, in <module>
    open_func()
  File "study-test/traceback-test/Demo03.py", line 14, in open_func
    pass_func_03()
  File "study-test/traceback-test/Demo03.py", line 11, in pass_func_03
    return pass_func_02()
  File "study-test/traceback-test/Demo03.py", line 8, in pass_func_02
    return pass_func_01()
  File "study-test/traceback-test/Demo03.py", line 5, in pass_func_01
    return main()
  File "study-test/traceback-test/Demo03.py", line 2, in main
    raise Exception("This is a test")
Exception: This is a test

如果出现报错会导致返回的报错链路过长,不适合对用户展示,我们就可以基于traceback包实现对于报错的重写

import sys
import _testcapi
import traceback

def main():
    raise Exception("This is a test")

def pass_func_01():
    return main()

def pass_func_02():
    return pass_func_01()

def pass_func_03():
    return pass_func_02()

def open_func():
    try:
        pass_func_03()
    except Exception as e:
        exc_type, exc_value, exc_traceback = sys.exc_info() # 获取到traceback需要的异常信息
        tb = traceback.extract_tb(exc_traceback)
        filtered_tb = [frame for frame in tb if "pass_func" not in frame[2]] # frame[2]是函数名称
        formatted_lines = traceback.format_list(filtered_tb)
        formatted_lines += traceback.format_exception_only(exc_type, exc_value)
        custom_traceback = ''.join(formatted_lines)
        try:
            raise exc_type('\n'+custom_traceback) from None
        except:
            tp, exc, tb = sys.exc_info()
            _testcapi.set_exc_info(tp, exc, tb.tb_next)
            del tp, exc, tb
            raise

if __name__ == "__main__":
    open_func()

>>>
Traceback (most recent call last):
  File "study-test/traceback-test/Demo03.py", line 36, in <module>
    open_func()
Exception: 
  File "study-test/traceback-test/Demo03.py", line 19, in open_func
    pass_func_03()
  File "study-test/traceback-test/Demo03.py", line 6, in main
    raise Exception("This is a test")
Exception: This is a test

在上述代码片中对报错进行了筛选,去掉了中间链路的报错信息,同时使用了_testcapi包实现了对报错函数的包裹,提供给开发者系统性的简化报错信息的方案。

你可能感兴趣的:(python,python)