python:traceback —— 打印或读取堆栈的跟踪信息

  • 简介
  • TracebackException 对象
  • StackSummary 对象
  • FrameSummary 对象
  • 回溯示例


简介

该模块提供了一个标准接口来提取、格式化和打印 Python 程序的堆栈跟踪结果。它完全模仿Python 解释器在打印堆栈跟踪结果时的行为。当您想要在程序控制下打印堆栈跟踪结果时,例如在“封装”解释器时,这是非常有用的。
这个模块定义了以下函数:

traceback.print_tb(tb, limit=None, file=None)
如果limit是正整数,那么从 traceback 对象 “tb” 输出最高 limit 个(从调用函数开始的)栈的堆栈回溯‎条目‎;如果 limit 是负数就输出 abs(limit) 个回溯条目;又如果 limit 被省略或者为 None,那么就会输出所有回溯条目。如果 file 被省略或为 None 那么就会输出至标准输出sys.stderr否则它应该是一个打开的文件或者文件类对象来接收输出

在 3.5 版更改: 添加了对负数值 limit 的支持

traceback.print_exception(exc, /, [value, tb, ]limit=None, file=None, chain=True)
打印回溯对象 tb 到 file 的异常信息和整个堆栈回溯。这和 print_tb() 比有以下方面不同:

如果 tb 不为 None,它将打印头部 Traceback (most recent call last):

它将在栈回溯之后打印异常类型和 value

如果 type(value) 为 SyntaxError 且 value 具有适当的格式,它会打印发生语法错误的行并用一个圆点来指明错误的大致位置。

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

可选的 limit 参数具有与 print_tb() 的相同含义。 如果 chain 为真值(默认),则链式异常(异常的 causecontext 属性)也将被打印出来,就像解释器本身在打印未处理的异常时一样。

在 3.5 版更改: etype 参数会被忽略并根据 value 推断出来。

在 3.10 版更改: etype 形参已被重命名为 exc 并且现在是仅限位置形参。

traceback.print_exc(limit=None, file=None, chain=True)
This is a shorthand for print_exception(sys.exception(), limit, file, chain).

traceback.print_last(limit=None, file=None, chain=True)
这是 print_exception(sys.last_type, sys.last_value, sys.last_traceback, limit, file, chain) 的简写。 通常它将只在异常到达交互提示之后才会起作用 (参见 sys.last_type)。

traceback.print_stack(f=None, limit=None, file=None)
如果 limit 为正数则打印至多 limit 个栈回溯条目(从发起调用点开始)。 在其他情况下,则打印最后 abs(limit) 个条目。 如果 limit 被省略或为 None,则会打印所有条目。 可选的 f 参数可被用来指明一个用于开始的替代栈。 可选的 file 参数具有与 print_tb() 的相同含义。

在 3.5 版更改: 添加了对负数值 limit 的支持

traceback.extract_tb(tb, limit=None)
返回一个 StackSummary 对象来代表从回溯对象 tb 提取的 “预处理” 栈回溯条目列表。 它适用于栈回溯的替代格式化。 可选的 limit 参数具有与 print_tb() 的相同含义。 “预处理” 栈回溯条目是一个 FrameSummary 对象,其中包含代表通常为栈回溯打印的信息的 filename, lineno, name 和 line 等属性。 line 是一个去除了前导和末尾空白符的字符串;如果源代码不可用则它将为 None。

traceback.extract_stack(f=None, limit=None)
从当前的栈帧提取原始回溯信息。 返回值具有与 extract_tb() 的相同格式。 可选的 f 和 limit 参数具有与 print_stack() 的相同含义。

traceback.format_list(extracted_list)
给定一个由元组或如 extract_tb() 或 extract_stack() 所返回的 FrameSummary 对象组成的列表,返回一个可打印的字符串列表。 结果列表中的每个字符串都对应于参数列表中具有相同索引号的条目。 每个字符串以一个换行符结束;对于那些源文本行不为 None 的条目,字符串也可能包含内部换行符。

traceback.format_exception_only(exc, /[, value])
使用 sys.last_value 等给出的异常值来格式化回溯中的异常部分。 返回值是一个字符串的列表,每个字符串都以换行符结束。 通常,此列表只包含单个字符串;但是,对于 SyntaxError 异常,它将包含多行并且(当打印时)会显示有关语法错误在何处发生的详细信息。 指明发生了哪种异常的消息将总是该列表中的最后一个字符串。

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

在 3.10 版更改: etype 形参已被重命名为 exc 并且现在是仅限位置形参。

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)
通过调用每个帧对象的 clear() 方法来清除回溯 tb 中所有栈帧的局部变量。

3.4 新版功能.

traceback.walk_stack(f)
从给定的帧开始访问 f.f_back 之后的栈,产生每一帧的帧和行号。 如果 f 为 None,则会使用当前栈。 这个辅助函数要与 StackSummary.extract() 一起使用。

3.5 新版功能.

traceback.walk_tb(tb)
访问 tb_next 之后的回溯并产生每一帧的帧和行号。 这个辅助函数要与 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)
捕获一个异常以便随后渲染。 limit, lookup_lines 和 capture_locals 的含义与 StackSummary 类的相同。

如果 compact 为真值,则只有 TracebackException 的 format 方法所需要的数据会被保存在类属性中。 特别地,context 字段只有在 cause 为 None 且 suppress_context 为假值时才会被计算。

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

cause
原始 cause 的 TracebackException。

context
原始 context 的 TracebackException。

suppress_context
来自原始异常的 suppress_context

3.11 新版功能.

stack
代表回溯的 StackSummary。

exc_type
原始回溯的类。

filename
针对语法错误 —— 错误发生所在的文件名。

lineno
针对语法错误 —— 错误发生所在的行号。

text
针对语法错误 —— 错误发生所在的文本。

offset
针对语法错误 —— 错误发生所在的文本内部的偏移量。

msg
针对语法错误 —— 编译器错误消息。

classmethod from_exception(exc, *, limit=None, lookup_lines=True, capture_locals=False)
捕获一个异常以便随后渲染。 limit, lookup_lines 和 capture_locals 的含义与 StackSummary 类的相同。

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

print(*, file=None, chain=True)
Print to file (default sys.stderr) the exception information returned by format().

3.11 新版功能.

format(*, chain=True)
格式化异常。

如果 chain 不为 True,则 causecontext 将不会被格式化。

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

指明发生了哪种异常的消息总会是输出中的最后一个字符串。

format_exception_only()
格式化回溯的异常部分。

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

通常,生成器会发出单个字符串;不过,对于 SyntaxError 异常,它会发出(当打印时)显示有关语法错误发生在何处的详细信息的多个行。

指明发生了哪种异常的消息总会是输出中的最后一个字符串。

在 3.10 版更改: 增加了 compact 形参。

StackSummary 对象

3.5 新版功能.

代表一个可被格式化的调用栈的 StackSummary 对象。

class traceback.StackSummary
classmethod extract(frame_gen, *, limit=None, lookup_lines=True, capture_locals=False)
构造一个来自帧生成器的 StackSummary 对象(如 walk_stack() 或 walk_tb() 所返回的一样)。

如果提供了 limit,则只从 frame_gen 提取指定数量的帧。 如果 lookup_lines 为 False,则返回的 FrameSummary 对象将不会读入它们的行,这使得创建 StackSummary 的开销更低(如果它不会被实际格式化这就会很有价值)。 如果 capture_locals 为 True 则每个 FrameSummary 中的局部变量会被捕获为对象表示形式。

classmethod from_list(a_list)
从所提供的 FrameSummary 对象列表或旧式的元组列表构造一个 StackSummary 对象。 每个元组都应当是以文件、行号、名称和行为元素的 4 元组。

format()
返回一个可打印的字符串列表。 结果列表中的每个字符串各自对应来自于栈的单独帧。 每个字符串都以一个换行符结束;对于带有源文本行的条目来说,字符串还可能包含内部换行符。

对于同一帧与行的长序列,将显示前几个重复项,后面跟一个指明之后的实际重复次数的摘要行。

3.11 新版功能.

FrameSummary 对象

3.5 新版功能.

A FrameSummary object represents a single frame in a traceback.

class traceback.FrameSummary(filename, lineno, name, lookup_line=True, locals=None, line=None)
代表回溯或栈中被格式化或打印的一个单独帧。 它有时可能还带有包括在其中的帧局部变量的字符串化版本。 如果 lookup_line 为 False,则不会查找源代码直到 FrameSummary 已经访问了 line 属性(这还将发生在将其转换为元组时)。 line 可能会被直接提供,并将完全阻止行查找的发生。 locals 是一个可选的局部变量字典,如果有提供的话这些变量的表示形式将被存储在摘要中以便随后显示。

回溯示例

这个简单示例是一个基本的读取-求值-打印循环,类似于(但实用性小于)标准 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)


下面的例子演示了打印和格式化异常与回溯的不同方式:

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 
 lumberjack()
 *** print_exception:
 Traceback (most recent call last):
 File “<doctest…>”, line 10, in 
 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 
 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 \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 >,
 <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 \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']