Skip to main content

29.9. traceback —打印或检索堆栈跟踪

源代码: Lib/traceback.py


此模块提供了一个标准接口来提取,格式化和打印Python程序的堆栈跟踪。它精确地模拟了Python解释器在打印堆栈跟踪时的行为。当你想在程序控制下打印堆栈跟踪时,例如在解释器周围的“包装器”中,这是非常有用的。

模块使用追踪对象—这是存储在 sys.last_traceback 变量中并作为第三项从 sys.exc_info() 返回的对象类型。

该模块定义了以下功能:

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

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

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

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

从追踪对象 tbfile 的打印异常信息和堆栈跟踪条目。这与 print_tb() 在以下方面不同:

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

  • 它在堆栈跟踪之后打印异常 etypevalue

  • 如果 etypeSyntaxError 并且 value 具有适当的格式,则它使用指示错误的大致位置的插入符来打印语法错误发生的行。

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

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

这是 print_exception(*sys.exc_info(), 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) 条目。如果省略 limitNone,则会打印所有条目。可选的 f 参数可用于指定要开始的备用堆栈帧。可选的 file 参数具有与 print_tb() 相同的含义。

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

traceback.extract_tb(tb, limit=None)

返回从追溯对象 tb 提取的“预处理”的堆栈跟踪条目的列表。它对堆栈跟踪的备用格式化很有用。可选的 limit 参数具有与 print_tb() 相同的含义。 “预处理”堆栈跟踪条目是表示通常为堆栈跟踪打印的信息的4元组(filename电话号码函数名text)。 text 是一个带有前导和尾随空格的字符串;如果源不可用,它是 None

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

从当前堆栈框架提取原始追溯。返回值具有与 extract_tb() 相同的格式。可选的 flimit 参数具有与 print_stack() 相同的含义。

traceback.format_list(extracted_list)

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

traceback.format_exception_only(etype, value)

格式化回溯的异常部分。参数是例如由 sys.last_typesys.last_value 给出的异常类型和值。返回值是一个字符串列表,每个以换行符结束。通常,列表包含单个字符串;然而,对于 SyntaxError 异常,它包含几行(当打印时)显示关于语法错误发生位置的详细信息。指示发生哪个异常的消息是列表中的始终最后一个字符串。

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

格式化堆栈跟踪和异常信息。参数具有与 print_exception() 的相应参数相同的含义。返回值是一个字符串列表,每个以换行符结尾,一些包含内部换行符。当这些线被连接和打印时,打印与 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 之后的堆栈,产生每个帧的帧和行号。如果 fNone,则使用当前堆栈。这个助手用于 StackSummary.extract()

3.5 新版功能.

traceback.walk_tb(tb)

tb_next 后面执行跟踪,产生每个帧的帧和行号。此助手与 StackSummary.extract() 一起使用。

3.5 新版功能.

该模块还定义了以下类:

29.9.1. TracebackException 对象

3.5 新版功能.

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

class traceback.TracebackException(exc_type, exc_value, exc_traceback, *, limit=None, lookup_lines=True, capture_locals=False)

捕获异常以供以后渲染。 limitlookup_linescapture_localsStackSummary 类相同。

请注意,当捕获本地时,它们也显示在追溯中。

__cause__

原始 __cause__TracebackException

__context__

原始 __context__TracebackException

__suppress_context__

原始异常的 __suppress_context__ 值。

stack

StackSummary 表示追溯。

exc_type

原始追溯的类。

filename

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

lineno

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

text

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

offset

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

msg

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

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

捕获异常以供以后渲染。 limitlookup_linescapture_localsStackSummary 类相同。

请注意,当捕获本地时,它们也显示在追溯中。

format(*, chain=True)

格式化异常。

如果 chain 不是 True,则 __cause____context__ 将不被格式化。

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

指示发生哪个异常的消息始终是输出中的最后一个字符串。

format_exception_only()

格式化回溯的异常部分。

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

通常,发电机发出单个串;然而,对于 SyntaxError 异常,它会发出几行(当打印时)显示关于语法错误发生位置的详细信息。

指示发生哪个异常的消息始终是输出中的最后一个字符串。

29.9.2. 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_linesFalse,返回的 FrameSummary 对象将不会读取它们的行,使得创建 StackSummary 的成本更便宜(如果实际上可能不被格式化,这可能是有价值的)。如果 capture_localsTrue,则每个 FrameSummary 中的局部变量被捕获作为对象表示。

classmethod from_list(a_list)

从提供的旧样式的元组列表构造 StackSummary 对象。每个元组应该是一个4元组,文件名,lineno,名称,行作为元素。

format()

返回准备打印的字符串列表。结果列表中的每个字符串对应于来自堆栈的单个帧。每个字符串以换行符结尾;字符串也可以包含内部换行符,对于具有源文本行的那些项目。

对于相同帧和线的长序列,示出了前几个重复,随后是表示进一步重复的确切数量的汇总线。

在 3.6 版更改: 现在缩写重复帧的长序列。

29.9.3. FrameSummary 对象

3.5 新版功能.

FrameSummary 对象表示回溯中的单个帧。

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

表示正在格式化或打印的回溯或堆栈中的单个帧。它可以可选地具有包括在其中的帧局部变量的字符串版本。如果 lookup_lineFalse,在 FrameSummary 访问 line 属性之前(在将其转换为元组时也会发生),不会查找源代码。 line 可以直接提供,并且将防止线查找发生。 locals 是可选的局部变量字典,如果提供的话,变量表示存储在摘要中以供以后显示。

29.9.4. 回溯示例

这个简单的例子实现了一个基本的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)

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

import sys, traceback

def lumberjack():
    bright_side_of_death()

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

try:
    lumberjack()
except IndexError:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    print("*** print_tb:")
    traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
    print("*** print_exception:")
    traceback.print_exception(exc_type, exc_value, exc_traceback,
                              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_type, exc_value,
                                          exc_traceback)))
    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_death()
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_death()
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...>", line 10, in <module>\n    lumberjack()\n',
 '  File "<doctest...>", line 4, in lumberjack\n    bright_side_of_death()\n',
 '  File "<doctest...>", line 7, in bright_side_of_death\n    return tuple()[0]\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_death>]
*** format_tb:
['  File "<doctest...>", line 10, in <module>\n    lumberjack()\n',
 '  File "<doctest...>", line 4, in lumberjack\n    bright_side_of_death()\n',
 '  File "<doctest...>", line 7, in bright_side_of_death\n    return tuple()[0]\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']