traceback — 打印或检索堆栈回溯

源代码: Lib/traceback.py


此模块提供了一个标准接口,用于提取、格式化和打印 Python 程序的堆栈回溯。它完全模拟了 Python 解释器打印堆栈回溯时的行为。当您想在程序控制下打印堆栈回溯时,这很有用,例如在解释器周围的“包装器”中。

该模块使用 回溯对象 — 这些是类型为 types.TracebackType 的对象,它们被分配给 __traceback__ 字段 BaseException 实例。

另请参见

模块 faulthandler

用于在发生故障、超时或用户信号后显式转储 Python 回溯。

模块 pdb

Python 程序的交互式源代码调试器。

该模块定义了以下函数

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

如果 limit 为正,则从 traceback 对象 tb(从调用者的帧开始)打印最多 limit 个堆栈跟踪条目。否则,打印最后 abs(limit) 个条目。如果省略 limitNone,则打印所有条目。如果省略 fileNone,则输出到 sys.stderr;否则,它应该是一个打开的 文件类文件对象 以接收输出。

3.5 版中已更改: 添加了负 limit 支持。

traceback.print_exception(exc, /, [value, tb, ]limit=None, file=None, chain=True)

将异常信息和堆栈跟踪条目从 traceback 对象 tb 打印到 file。这与 print_tb() 有以下不同之处

  • 如果 tb 不为 None,则打印标题 Traceback (most recent call last):

  • 它在堆栈跟踪之后打印异常类型和 value

  • 如果 type(value)SyntaxErrorvalue 具有适当的格式,则打印发生语法错误的行,并用插入符号指示错误的近似位置。

从 Python 3.10 开始,可以将异常对象作为第一个参数传递,而不是传递 valuetb。如果提供了 valuetb,则为了提供向后兼容性,将忽略第一个参数。

可选的 limit 参数与 print_tb() 的含义相同。如果 chain 为 true(默认值),则还会打印链接的异常(异常的 __cause____context__ 属性),就像解释器本身在打印未处理的异常时所做的那样。

3.5 版中已更改: 忽略 etype 参数,并从 value 的类型推断它。

3.10 版中已更改: etype 参数已重命名为 exc,现在仅限于位置。

traceback.print_exc(limit=None, file=None, chain=True)

这是 print_exception(sys.exception(), limit, file, chain) 的简写。

traceback.print_last(limit=None, file=None, chain=True)

这是 print_exception(sys.last_exc, limit, file, chain) 的简写。通常,它仅在异常到达交互式提示符后才起作用(请参阅 sys.last_exc)。

traceback.print_stack(f=None, limit=None, file=None)

如果 limit 为正,则打印最多 limit 个堆栈跟踪项(从调用点开始)。否则,打印最后 abs(limit) 个项。如果省略 limitNone,则打印所有项。可选的 f 参数可用于指定要开始的备用 堆栈帧。可选的 file 参数与 print_tb() 的含义相同。

3.5 版中已更改: 添加了负 limit 支持。

traceback.extract_tb(tb, limit=None)

返回一个StackSummary对象,表示从traceback 对象tb中提取的“预处理”堆栈跟踪条目列表。它可用于堆栈跟踪的备用格式。可选的limit参数与print_tb()的含义相同。“预处理”堆栈跟踪条目是一个FrameSummary对象,包含属性filenamelinenonameline,表示通常为堆栈跟踪打印的信息。

traceback.extract_stack(f=None, limit=None)

从当前堆栈帧中提取原始 traceback。返回值的格式与extract_tb()相同。可选的flimit参数与print_stack()的含义相同。

traceback.format_list(extracted_list)

给定由extract_tb()extract_stack()返回的元组或FrameSummary对象列表,返回一个准备打印的字符串列表。结果列表中的每个字符串对应于参数列表中具有相同索引的项目。每个字符串都以换行符结尾;对于源文本行不是None的那些项目,字符串可能还包含内部换行符。

traceback.format_exception_only(exc, /[, value])

使用异常值(例如 sys.last_value 提供的异常值)格式化回溯中的异常部分。返回值是一个字符串列表,每个字符串以换行符结尾。该列表包含异常消息,通常为单个字符串;但是,对于 SyntaxError 异常,它包含多行(在打印时)显示有关语法错误发生位置的详细信息。在消息之后,列表包含异常的 notes

从 Python 3.10 开始,可以将异常对象作为第一个参数传递,而不是传递 value。如果提供了 value,则为了提供向后兼容性,将忽略第一个参数。

3.10 版中已更改: etype 参数已重命名为 exc,现在仅限于位置。

在版本 3.11 中更改:返回的列表现在包括附加到异常的任何 notes

traceback.format_exception(exc, /, [value, tb, ]limit=None, chain=True)

格式化堆栈跟踪和异常信息。参数与 print_exception() 的相应参数具有相同的含义。返回值是一个字符串列表,每个字符串以换行符结尾,有些字符串包含内部换行符。当这些行连接并打印时,打印的文本与 print_exception() 打印的文本完全相同。

3.5 版中已更改: 忽略 etype 参数,并从 value 的类型推断它。

在版本 3.10 中更改:此函数的行为和签名已修改为与 print_exception() 匹配。

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

这类似于 print_exc(limit),但返回一个字符串,而不是打印到文件。

traceback.format_tb(tb, limit=None)

代码的简写形式format_list(extract_tb(tb, limit))

traceback.format_stack(f=None, limit=None)

代码的简写形式format_list(extract_stack(f, limit))

traceback.clear_frames(tb)

清除tracebacktb 中所有堆栈帧的局部变量,方法是调用每个frame objectclear() 方法。

在 3.4 版本中添加。

traceback.walk_stack(f)

从给定的帧开始,沿着f.f_back 遍历堆栈,为每个帧生成帧和行号。如果fNone,则使用当前堆栈。此帮助程序与StackSummary.extract() 一起使用。

在 3.5 版本中添加。

traceback.walk_tb(tb)

沿着tb_next 遍历 traceback,为每个帧生成帧和行号。此帮助程序与StackSummary.extract() 一起使用。

在 3.5 版本中添加。

该模块还定义了以下类

TracebackException 对象

在 3.5 版本中添加。

TracebackException 对象从实际异常中创建,以捕获数据,以便以后以轻量级方式进行打印。

class traceback.TracebackException(exc_type, exc_value, exc_traceback, *, limit=None, lookup_lines=True, capture_locals=False, compact=False, max_group_width=15, max_group_depth=10)

捕获异常以供以后呈现。limitlookup_linescapture_localsStackSummary 类的相同。

如果 compact 为真,则仅将 TracebackExceptionformat() 方法所需的数据保存在类属性中。特别是,__context__ 字段仅在 __cause__None__suppress_context__ 为假时才计算。

请注意,当捕获局部变量时,它们也会显示在回溯中。

max_group_widthmax_group_depth 控制异常组的格式(参见 BaseExceptionGroup)。深度是指组的嵌套级别,宽度是指单个异常组的异常数组的大小。当任一限制被超过时,格式化的输出将被截断。

在 3.10 版中更改:添加了 compact 参数。

在 3.11 版中更改:添加了 max_group_widthmax_group_depth 参数。

__cause__

原始 __cause__TracebackException

__context__

原始 __context__TracebackException

exceptions

如果 self 表示 ExceptionGroup,则此字段保存表示嵌套异常的 TracebackException 实例列表。否则为 None

在版本 3.11 中添加。

__suppress_context__

来自原始异常的 __suppress_context__ 值。

__notes__

来自原始异常的 __notes__ 值,如果异常没有任何注释,则为 None。如果不是 None,则在异常字符串之后以回溯格式显示。

在版本 3.11 中添加。

stack

表示回溯的 StackSummary

exc_type

原始回溯的类。

filename

对于语法错误 - 发生错误的文件名。

lineno

对于语法错误 - 发生错误的行号。

end_lineno

对于语法错误 - 发生错误的结束行号。如果不存在,则可以为 None

在版本 3.10 中添加。

text

对于语法错误 - 发生错误的文本。

offset

对于语法错误 - 发生错误的文本中的偏移量。

end_offset

对于语法错误 - 发生错误的文本中的结束偏移量。如果不存在,可以为 None

在版本 3.10 中添加。

msg

对于语法错误 - 编译器错误消息。

classmethod from_exception(exc, *, limit=None, lookup_lines=True, capture_locals=False)

捕获异常以供以后呈现。limitlookup_linescapture_localsStackSummary 类的相同。

请注意,当捕获局部变量时,它们也会显示在回溯中。

print(*, file=None, chain=True)

format() 返回的异常信息打印到 file(默认 sys.stderr)。

在版本 3.11 中添加。

format(*, chain=True)

格式化异常。

如果 chain 不为 True__cause____context__ 将不会被格式化。

返回值是一个字符串生成器,每个字符串以换行符结尾,有些包含内部换行符。 print_exception() 是此方法的包装器,它只将行打印到文件中。

format_exception_only()

格式化回溯中的异常部分。

返回值是一个字符串生成器,每个字符串以换行符结尾。

生成器会发出异常消息,后跟其注释(如果有)。异常消息通常是一个字符串;但是,对于 SyntaxError 异常,它由几行组成,(在打印时)显示有关语法错误发生位置的详细信息。

在 3.11 版本中更改: 异常的 notes 现在包含在输出中。

StackSummary 对象

在 3.5 版本中添加。

StackSummary 对象表示一个准备格式化的调用堆栈。

class traceback.StackSummary
classmethod extract(frame_gen, *, limit=None, lookup_lines=True, capture_locals=False)

从帧生成器(例如 walk_stack()walk_tb() 返回的生成器)构造 StackSummary 对象。

如果提供了 limit,则仅从 frame_gen 中获取这么多帧。如果 lookup_linesFalse,则返回的 FrameSummary 对象尚未读取其行,从而降低了创建 StackSummary 的成本(如果它实际上可能无法格式化,这可能很有价值)。如果 capture_localsTrue,则每个 FrameSummary 中的局部变量将被捕获为对象表示形式。

在 3.12 版本中更改: 不再将 repr() 在局部变量上引发异常(当 capture_localsTrue)传播到调用者。

classmethod from_list(a_list)

从提供的 FrameSummary 对象或旧式元组列表构建 StackSummary 对象。每个元组应为 4 元组,元素为 filenamelinenonameline

format()

返回可用于打印的字符串列表。结果列表中的每个字符串对应于堆栈中的单个 frame。每个字符串以换行符结尾;对于包含源文本行的项目,字符串还可能包含内部换行符。

对于相同 frame 和 line 的长序列,将显示前几个重复项,然后显示一个摘要行,说明确切的进一步重复次数。

在版本 3.6 中更改:现在已缩写重复 frame 的长序列。

format_frame_summary(frame_summary)

返回一个字符串,用于打印堆栈中涉及的 frames 之一。此方法针对每个 FrameSummary 对象调用,以便由 StackSummary.format() 打印。如果它返回 None,则从输出中省略 frame。

在版本 3.11 中添加。

FrameSummary 对象

在 3.5 版本中添加。

FrameSummary 对象表示 traceback 中的单个 frame

class traceback.FrameSummary(filename, lineno, name, lookup_line=True, locals=None, line=None)

表示 frame 中的单个 traceback 或正在格式化或打印的堆栈。它可以包含其中包含的 frame 本地变量的字符串化版本。如果 lookup_lineFalse,则不会查找源代码,直到 FrameSummary 具有 line 属性访问(在将其转换为 tuple 时也会发生)。line 可以直接提供,并且将完全阻止行查找。locals 是一个可选的局部变量字典,如果提供,则变量表示将存储在摘要中以供以后显示。

FrameSummary 实例具有以下属性

filename

此 frame 的源代码的文件名。相当于访问 f.f_code.co_filename 上的 frame 对象 f

lineno

此 frame 的源代码的行号。

name

相当于访问 f.f_code.co_name 上的 frame 对象 f

line

一个字符串,表示此 frame 的源代码,其中去掉了前导和尾随空格。如果源代码不可用,则为 None

Traceback 示例

此简单示例实现了一个基本的 read-eval-print 循环,类似于(但不如)标准 Python 交互式解释器循环。有关解释器循环的更完整实现,请参阅 code 模块。

import sys, traceback

def run_user_code(envdir):
    source = input(">>> ")
    try:
        exec(source, envdir)
    except Exception:
        print("Exception in user code:")
        print("-"*60)
        traceback.print_exc(file=sys.stdout)
        print("-"*60)

envdir = {}
while True:
    run_user_code(envdir)

以下示例演示了打印和格式化异常和 traceback 的不同方法

import sys, traceback

def lumberjack():
    bright_side_of_life()

def bright_side_of_life():
    return tuple()[0]

try:
    lumberjack()
except IndexError:
    exc = sys.exception()
    print("*** print_tb:")
    traceback.print_tb(exc.__traceback__, limit=1, file=sys.stdout)
    print("*** print_exception:")
    traceback.print_exception(exc, 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)))
    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 "<doctest...>", line 10, in <module>
    lumberjack()
*** print_exception:
Traceback (most recent call last):
  File "<doctest...>", line 10, in <module>
    lumberjack()
  File "<doctest...>", line 4, in lumberjack
    bright_side_of_life()
IndexError: tuple index out of range
*** print_exc:
Traceback (most recent call last):
  File "<doctest...>", line 10, in <module>
    lumberjack()
  File "<doctest...>", line 4, 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 "<doctest default[0]>", line 10, in <module>\n    lumberjack()\n',
 '  File "<doctest default[0]>", line 4, in lumberjack\n    bright_side_of_life()\n',
 '  File "<doctest default[0]>", line 7, in bright_side_of_life\n    return tuple()[0]\n           ~~~~~~~^^^\n',
 'IndexError: tuple index out of range\n']
*** extract_tb:
[<FrameSummary file <doctest...>, line 10 in <module>>,
 <FrameSummary file <doctest...>, line 4 in lumberjack>,
 <FrameSummary file <doctest...>, line 7 in bright_side_of_life>]
*** format_tb:
['  File "<doctest default[0]>", line 10, in <module>\n    lumberjack()\n',
 '  File "<doctest default[0]>", line 4, in lumberjack\n    bright_side_of_life()\n',
 '  File "<doctest default[0]>", line 7, in bright_side_of_life\n    return tuple()[0]\n           ~~~~~~~^^^\n']
*** tb_lineno: 10

以下示例显示了打印和格式化堆栈的不同方式

>>> import traceback
>>> def another_function():
...     lumberstack()
...
>>> def lumberstack():
...     traceback.print_stack()
...     print(repr(traceback.extract_stack()))
...     print(repr(traceback.format_stack()))
...
>>> another_function()
  File "<doctest>", line 10, in <module>
    another_function()
  File "<doctest>", line 3, in another_function
    lumberstack()
  File "<doctest>", line 6, in lumberstack
    traceback.print_stack()
[('<doctest>', 10, '<module>', 'another_function()'),
 ('<doctest>', 3, 'another_function', 'lumberstack()'),
 ('<doctest>', 7, 'lumberstack', 'print(repr(traceback.extract_stack()))')]
['  File "<doctest>", line 10, in <module>\n    another_function()\n',
 '  File "<doctest>", line 3, in another_function\n    lumberstack()\n',
 '  File "<doctest>", line 8, in lumberstack\n    print(repr(traceback.format_stack()))\n']

此最后一个示例演示了最后的几个格式化函数

>>> import traceback
>>> traceback.format_list([('spam.py', 3, '<module>', 'spam.eggs()'),
...                        ('eggs.py', 42, 'eggs', 'return "bacon"')])
['  File "spam.py", line 3, in <module>\n    spam.eggs()\n',
 '  File "eggs.py", line 42, in eggs\n    return "bacon"\n']
>>> an_error = IndexError('tuple index out of range')
>>> traceback.format_exception_only(type(an_error), an_error)
['IndexError: tuple index out of range\n']