traceback 是 Python 标准库中的一个模块,它提供了一组用于提取、格式化和打印程序执行过程中的堆栈跟踪信息的工具。当程序发生异常且未被捕获时,Python 会自动生成一个堆栈跟踪,显示出错的位置和调用栈。这有助于开发者理解和调试程序中出现的问题。
当程序发生异常时,traceback模块可以用来捕获和格式化相关的堆栈信息。这有助于开发者快速定位问题所在。格式化的堆栈信息通常包括以下内容:
traceback模块提供了多种函数来格式化和打印堆栈信息,下面是一些常用的函数:
traceback.print_tb(tb, limit=None, file=None)
traceback.print_exception(etype, value, tb, limit=None, file=None, chain=True)
traceback.format_tb(tb, limit=None)
traceback.format_exception(etype, value, tb, limit=None, chain=True)
traceback.format_exc(limit=None, chain=True)
下面有一个多层嵌套的函数调用
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
包实现了对报错函数的包裹,提供给开发者系统性的简化报错信息的方案。