# 29.9. `traceback` - 打印或检索堆栈跟踪

源代码： Lib / traceback.py

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

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

该模块定义了以下功能：

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

  如果limit为正，则从跟踪对象tb打印限制堆栈跟踪条目。否则，打印最后的`abs(limit)`条目。如果省略限制或`None`，将打印所有条目。如果省略文件或`None`，输出将转到`sys.stderr`；否则应该是一个打开的文件或类似文件的对象来接收输出。

  在3.5版本中有更改：添加了负面限制支持。

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

  从追踪对象tb到文件中打印异常信息和堆栈跟踪条目。这与`print_tb()`有以下不同：

  - 如果tb不是`None`，则会打印标头`Traceback （最近 t6> call last）：`
  - 它在堆栈跟踪之后打印异常etype和值
  - 如果etype是`SyntaxError`和value具有适当的格式，则会使用插入符号来显示语法错误发生的行，错误。

  可选的limit参数与`print_tb()`具有相同的含义。如果chain为真（默认值），那么也将打印链接异常（`__cause__`或`__context__`属性），如解释器本身在打印未处理的异常时执行。

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

  这是`print_exception（* sys.exc_info()， limit， 文件， 链） t4 >`。

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

  这是`print_exception（sys.last_type， sys.last_value， sys.last_traceback， t4> 文件， 链）`。通常，只有在异常到达一个交互式提示符后，它才会工作（参见`sys.last_type`）。

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

  如果limit为正，则打印到limit堆栈跟踪条目（从调用点开始）。否则，打印最后的`abs(limit)`条目。如果省略限制或`None`，将打印所有条目。可选的f参数可用于指定要开始的备用堆栈帧。可选的文件参数与`print_tb()`具有相同的含义。

  在3.5版本中有更改：添加了负面限制支持。

`traceback.``extract_tb`(tb, limit=None)

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

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

  从当前堆栈帧提取原始追溯。返回值具有与`extract_tb()`相同的格式。可选的f和限制参数与`print_stack()`具有相同的含义。

`traceback.``format_list`(extracted_list)

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

`traceback.``format_exception_only`(etype, value)

  格式化回溯的异常部分。参数是例如由`sys.last_type`和`sys.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`后的堆栈，得到每个帧的帧和行号。如果f为`None`，则使用当前堆栈。此辅助程序与`StackSummary.extract()`一起使用。

  版本3.5中的新功能。

`traceback.``walk_tb`(tb)

  在`tb_next`之后执行回溯，得到每个帧的帧和行号。此辅助程序与`StackSummary.extract()`一起使用。

  版本3.5中的新功能。

该模块还定义了以下类：

## 29.9.1. `TracebackException` Objects

版本3.5中的新功能。

`TracebackException`对象根据实际异常创建，以捕获数据，以便稍后以轻量级方式打印。

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

  捕获异常以供以后渲染。限制，lookup_lines和capture_locals与`StackSummary`类相同。

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

  `__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)

    捕获异常以供以后渲染。限制，lookup_lines和capture_locals与`StackSummary`类相同。

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

  `format`(*, chain=True)

    格式化异常。

    如果chain不是`True`，则`__cause__`和`__context__`

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

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

  `format_exception_only`()

    格式化回溯的异常部分。

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

    通常，生成器发射单个字符串；但是，对于`SyntaxError`异常，它会发出几行（打印时）显示有关语法错误发生位置的详细信息。

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

## 29.9.2. `StackSummary` Objects

版本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)

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

## 29.9.3. `FrameSummary` Objects

版本3.5中的新功能。

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

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

  表示正在格式化或打印的回溯或堆栈中的单个帧。它可以可选地具有包括在其中的帧本地的字符串版本。如果lookup_line为`False`，则直到`FrameSummary`访问`line`属性也发生在将其转换为元组时）。`line`可以直接提供，并且将防止线查找完全发生​​。locals是一个可选的局部变量字典，如果提供，变量表示存储在摘要中以供以后显示。

## 29.9.4. Traceback Examples

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