>>> from env_helper import info; info()
页面更新时间: 2023-12-28 15:27:01
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-16-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

4.10. 使用traceback获取钱信息

当程序产生异常的时候,最需要面对异常的其实是开发人员,他们需要更多的异常提示 的信息,以便调试程序中潜在的错误和问题。 先来看一个简单的例子:

>>> gList=['a','b','b','c','e']
>>> def f():
>>>     gList[5]
>>>     return g()
>>> def g():
>>>     return h()
>>> def i():
>>>     gList.append('i')
>>>     print(gList[6])
>>> if __name__=='__main__':
>>>     try:
>>>         f()
>>>     except IndexError as ex:
>>>         print ("sorry")
>>>         print(ex)
sorry
list index out of range

程序运行输出如上。

信息提示有异常产生,对于用户这点还算是较为友好的,那么对于开发人员,他如何快速地知道错误发生在哪里呢? 逐行检查代码吗?对于简单的程序,这也不失为一个办法,但 在较为复杂的应用程序中这个方法就显得有点低效了。

面对异常开发人员最希望看到的往往 是异常发生时候的现场信息, tmceback 模块可以满足这个需求,它会输出完整的栈信息。

将上述代码异常部分修改如下:

>>> gList=['a','b','b','c','e']
>>> def f():
>>>     gList[5]
>>>     return g()
>>> def g():
>>>     return h()
>>> def i():
>>>     gList.append('i')
>>>     print(gList[6])
>>> if __name__=='__main__':
>>>     try:
>>>         f()
>>>     except IndexError as ex:
>>>         print ("sorry")
>>>         print(ex)
>>>         import traceback
>>>         traceback.print_exc()
sorry
list index out of range
Traceback (most recent call last):
  File "/tmp/ipykernel_13055/3406637610.py", line 12, in <module>
    f()
  File "/tmp/ipykernel_13055/3406637610.py", line 3, in f
    gList[5]
    ~~~~~^^^
IndexError: list index out of range

程序运行会输出异常发生时候完整的栈信息,包括调用顺序、异常发生的语句、错误类 型等

traceback.print_exc() 方法打印出的信息包括3部分:

  • 错误类型(IndexError)

  • 错误对应 的值(list index out of range)

  • 具体的trace信息,包括文件名、具体的行号、函数名以及 对应的源代码。

Traceback模块提供了一系列方法来获取和显示异常发生时候的trace相关信 息.下面列举几个常用的方法:

  1. traceback.print_exception{iype, value, traceback[, limit[, file]]) , 根据 limit 的设置打 印找信息.file为None的情况下定位到 sys.stderr ,否则则写入文件;其中 type % value、 traceback 这3个参数对应的值可以从sys.exc_info() 中获取。

  2. raceback,print_cxc([limitl, file]]) ,为 print_exception() 涵数的缩写,不需要传人 type, valuetraceback 这 3 个参数

  3. traceback_format_exc([Hmit]) , 与 print_exc() 类似,区别在于返回形式为宇符串。

  4. traceback.extract_stack([file,[, limit]]) , 从当前栈_贞中提取 trace 信息。

读者可以参看Python文档获取更多关于traceback所提供的抽取、格式化或者打印程序 运行时候的栈跟踪信息的方法。

本质上模块trackback获取异常相关的数据都是通过sys.exc_info()函数得到的。当有异常发生的时候,该函数以元组的形式返回(type, value, traceback), 其中type为异常的类型,value为异常本身,tracebaclc为异常发生时候的调用和堆栈信息, 它是一个traceback对象,对象中包含出错的行数、位置等数据。

上面的例子中也可以通过如下方式输出异常发生时候的详细信息:

>>> import sys
>>> tb_type,tb_bal,exc_tb=sys.exc_info()
>>> for f,l,fc,su in traceback.extract_tb(exc_tb):
>>>     print("%-23s :%s '%s' in %s ()" %(f,l,fc,su))

实际上除了 traceback模块本身,inspect模块也提供了获取traceback对象的接口, inspect.trace([context])可以返回当前帧对象以及异常发生时进行捕获的帧对象之间的所有栈 帧记录列表,因此第一个记录代表当前调用对象,最后一个代表异常发生时候的对象。其 中每一个列表元素都是一个由6个元素组成的元组:(frame对象,文件名,当前行号,函数 名.源代码列表.当前行在源代码列表中的位置)。本节开头的例子在异常部分使用inspect.trace()来获取异常发生时候的堆栈信息,其部分输出结果如下:

[(frame object at Ox022CB480>,

testinspect.py,

23, <module>', ['t f 0n'] r 0) ,]

此外如果想进一步追踪函数调用的情况,还可以通过inspect模块的inspect.stack()函数 査看函数层级调用的栈相信信息。因此,当异常发生的时候,合理使用上述模块中的方法可 以快速地定位程序中的问题所在。