📜  Python中的回溯

📅  最后修改于: 2022-05-13 01:54:29.422000             🧑  作者: Mango

Python中的回溯

Traceback是一个Python模块,它提供了一个标准接口来提取、格式化和打印Python程序的堆栈跟踪。当它打印堆栈跟踪时,它完全模仿了Python解释器的行为。当您想在任何步骤打印堆栈跟踪时很有用。它们通常在发生异常时出现。由于回溯提供了有关异常的所有信息,因此跟踪和修复它变得更加容易。

异常堆栈跟踪的一般结构:

Traceback for most recent call
Location of the program 
Line in the program where error was encountered
Name of the error: relevant information about the exception 

例子 :

Traceback (most recent call last):
  File "C:/Python27/hdg.py", line 5, in 
    value = A[5]
IndexError: list index out of range

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

模块中的功能

  • 追溯。 print_tb (tb, limit = None, file = None) :如果 limit 为正,则从 traceback 对象 tb 打印最多限制堆栈跟踪条目。否则,打印最后的 abs(limit) 条目。如果省略限制或无,则打印所有条目。如果 file 被省略或 None,则输出到 sys.stderr;否则它应该是一个打开的文件或类似文件的对象来接收输出。
  • 追溯。 print_exception (etype, value, tb, limit = None, file = None, chain = True) :将异常信息和堆栈跟踪条目从 traceback 对象 tb 打印到文件。如果 tb 不是 None,它会打印一个标头 Traceback (last recent call last): 。它在堆栈跟踪之后打印异常 etype 和 value。如果 type(value) 是 SyntaxError 并且 value 具有适当的格式,它会打印出现语法错误的行,并用插入符号指示错误的大致位置。
  • 追溯。 print_exc (limit = None, file = None, chain = True) :这是 print_exception(*sys.exc_info(), limit, file, chain) 的简写。
  • 追溯。 print_last (limit = None, file = None, chain = True) :仅在异常到达交互式提示后才有效。这是 print_exception(sys.last_type, sys.last_value, sys.last_traceback, limit, file, chain) 的简写。
  • 追溯。 print_stack (f = None, limit = None, file = None) :如果 limit 为正,则打印到 limit 堆栈跟踪。否则,打印最后的 abs(limit) 条目。如果省略限制或无,则打印所有条目。可选的 f 参数可用于指定要启动的备用堆栈帧。
  • 追溯。 extract_tb (tb, limit = None) :返回一个StackSummary对象,表示从 traceback 对象 tb 中提取的“预处理”堆栈跟踪条目( FrameSummary对象包含属性文件名、行号、名称和行)列表。它对于堆栈跟踪的替代格式很有用。
  • 追溯。 extract_stack (f = None, limit = None) :从当前堆栈帧中提取原始回溯。返回值的格式与 extract_tb() 的格式相同。
  • 追溯。 format_list (extracted_list) :给定元组列表或FrameSummary对象返回准备打印的字符串列表。结果列表中的每个字符串对应于参数列表中具有相同索引的项目。每个字符串都以换行符结尾;字符串也可能包含内部换行符。
  • 追溯。 format_exception_only (etype, value) :格式化回溯的异常部分。参数是异常类型和值,例如由 sys.last_type 和 sys.last_value 给出。它返回一个字符串列表,每个字符串都以新行结尾。
  • 追溯。 format_exception (etype, value, tb, limit = None, chain = True) :格式化堆栈跟踪和异常信息。这些参数与 print_exception() 的相应参数具有相同的含义。它返回一个字符串列表,每个字符串都以换行符结尾,有些也有内部换行符。当这些行被连接并打印时,它们会生成与 print_exception() 完全相同的输出。
  • 追溯。 format_exc (limit = None, chain = True) :这类似于 print_exc(limit) ,只是它返回一个字符串而不是打印到文件。
  • 追溯。 format_tb (tb, limit = None) : format_list(extract_tb(tb, limit)) 的简写。
  • 追溯。 format_stack (f = None, limit = None) : format_list(extract_stack(f, limit)) 的简写。
  • 追溯。 clear_frames (tb) :通过调用每个帧对象的 clear() 方法清除回溯 tb 中所有堆栈帧的局部变量。
  • 追溯。 walk_stack (f) :从给定帧开始跟随 f.f_back 走一个栈,为每一帧产生帧和行号。如果 f 为 None,则使用当前堆栈。此帮助器与 StackSummary.extract() 一起使用。
  • 追溯。 walk_tb (tb) :跟踪 tb_next 之后的回溯,产生每一帧的帧和行号。此帮助器与 StackSummary.extract() 一起使用。

示例:打印异常堆栈跟踪的程序。

# importing module
import traceback
  
# declaring array
A = [1, 2, 3, 4]
  
try:
    value = A[5]
      
except:
    # printing stack trace
    traceback.print_exc()
  
# out of try-except
# this statement is to show that the program continues 
# normally after the exception is handled
print("end of program")

输出 :

Traceback (most recent call last):
  File "C:/Python27/van.py", line 8, in 
    value = A[5]
IndexError: list index out of range
end of program
>>> 

模块中的类

TracebackeException 类: TracebackException对象是根据实际异常创建的,以捕获数据以供以后打印。

TracebackException类包含以下对象:

  • __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) :捕获异常以供以后渲染。
  • format(*, chain=True) :格式化异常。如果 chain 不是 True, __cause____context__将不会被格式化。它返回每个以换行符结尾的字符串,并且很少有内部换行符。指示发生了哪个异常的消息始终是输出中的最后一个字符串。
  • format_exception_only() :格式化回溯的异常部分。它还返回以换行符结尾的字符串。通常,生成器会发出一个字符串;但是,对于SyntaxError异常,它会发出几行(打印时)显示有关语法错误发生位置的详细信息。指示发生了哪个异常的消息始终是输出中的最后一个字符串。

例子 :

# importing the modules
import traceback
import sys
  
a=3
b=0
try:
    a/b
except Exception as e:
    exc_type, exc_value, exc_tb = sys.exc_info()
    tb = traceback.TracebackException(exc_type, exc_value, exc_tb)
    print(''.join(tb.format_exception_only()))

输出 :

ZeroDivisonError: division by zero

StackSummary 类:该类的对象代表一个准备好格式化的调用堆栈。

class traceback.StackSummary
  • classmethod extract(frame_gen, *, limit = None, lookup_lines = True, capture_locals = False) :从帧生成器构造 StackSummary 对象。如果提供了限制,则只获取这么多帧。如果 lookup_lines 为 False,则返回的 FrameSummary 对象还没有读入它们的行,从而降低了创建 StackSummary 的成本。如果 capture_locals 为 True,则每个 FrameSummary 中的局部变量将被捕获为对象表示。
  • classmethod from_list(a_list) :从提供的 FrameSummary 对象列表或旧式元组列表构造 StackSummary 对象。
  • format() :返回准备打印的字符串列表。结果列表中的每个字符串对应于堆栈中的单个帧。每个字符串都以换行符结尾;字符串也可能包含内部换行符。对于同一帧和同一行的长序列,会显示前几次重复,然后是总结行,说明进一步重复的确切次数。然而,在较新的版本中,重复帧的长序列被缩短了。

例子 :

# importing the modules
import traceback
import sys
  
def call1(f):
  
  # inside call1()
  # call1() calling call2()
  call2(f)
  
def call2(f):
  # inside call2()
  # calling f()
  f()
  
def f():
    
    # inside f()
    summary = traceback.StackSummary.extract(
        traceback.walk_stack(None)
    )
    print(''.join(summary.format()))
  
# calling f() using call1()
call1(f)

输出 :

File "main.py", line 19, in f
    summary = traceback.StackSummary.extract(
  File "main.py", line 14, in call2
    f()
  File "main.py", line 9, in call1
    call2(f)
  File "main.py", line 25, in 
    call1(f)

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

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

它表示正在格式化或打印的回溯或堆栈中的单个帧。它可以选择在其中包含框架的字符串化版本。如果 lookup_line 为 False,则在 FrameSummary 访问 line 属性之前不会查找源代码。可以直接提供该行,并且将完全防止行查找发生。 Locals 是一个可选的局部变量字典,如果提供,变量表示将存储在摘要中以供以后显示。

例子 :

# importing the modules
import traceback
import sys
  
def call1(f):
  
    # inside call1()
    # call1() calling call2()
    call2(f)
  
def call2(f):
    # inside call2()
    # calling f()
    f()
      
template = (
    '{frame.filename}:{frame.lineno}:{frame.name}:\n'
    '    {frame.line}'
)
  
def f():
    summary = traceback.StackSummary.extract(
        traceback.walk_stack(None)
    )
    for frame in summary:
        print(template.format(frame=frame))
  
# calling f() through call1()
call1(f)

输出 :

main.py:21:f:
    summary = traceback.StackSummary.extract(
main.py:13:call2:
    f()
main.py:8:call1:
    call2(f)
main.py:28::
    call1(f)

参考-

  • https://文档。 Python.org/3/library/traceback.html#traceback.extract_tb
  • https://pymotw.com/3/traceback/