回溯 什么是Python回溯? Traceback

当一个异常在你的代码中被引发时,Python会打印一个traceback(回溯) 。如果你是第一次看到回溯输出,或者你不知道它在告诉你什么,那么它可能会让你不知所措 。但是Python回溯具有丰富的信息,可以帮助你诊断和修复代码中引发异常的原因 。理解Python回溯提供了什么信息对于成为一个更好的Python程序员至关重要 。
在本教程结束时,你将能够:

  • 理解你下一次遇到的回溯
  • 识别一些很常见的回溯
  • 在处理异常的同时成功记录回溯
什么是Python回溯?回溯是一个报告,其中包含在你的代码中某个特定点上执行的函数调用 。回溯有很多名称,包括堆栈跟踪、堆栈回溯、向后追溯,也许还有其他名称 。在Python中,使用的术语是回溯 。
当你的程序引发一个异常时,Python将打印当前回溯信息以帮助你知道哪里出错了 。下面是一个例子来说明这种情况:
回溯 什么是Python回溯? Traceback

文章插图
 
在这里,我们使用参数someone调用greet() 。但是,在greet()中,这个变量名没有被使用 。相反,它在print()调用中被错误拼写为someon 。
注意:本教程假设你理解Python异常 。如果你不熟悉或者只是想复习一下,那么你应该查看《Python异常:介绍》 。
当你运行这个程序时,你会得到以下回溯:
回溯 什么是Python回溯? Traceback

文章插图
 
此回溯输出包含你诊断问题所需的所有信息 。回溯输出的最后一行告诉你引发的是什么类型的异常,以及关于此异常的一些相关信息 。回溯的前几行指出了引发异常的代码 。
在上面的回溯中,该异常是一个NameError,这意味着有一个对未定义的名称(变量、函数、类)的引用 。在本例中,被引用的名称是someon 。
本例中的最后一行有足够的信息来帮助你解决问题 。在代码中搜索名称someon时(这是一个拼写错误)将为你指明正确的方向 。然而,你的代码通常要比这个例子复杂得多 。
如何阅读Python回溯?当你试图确定代码中引发异常的原因时,Python回溯中包含许多有用的信息 。在本节中,你将浏览不同的回溯,以便理解回溯中包含的不同信息 。
Python回溯概述
每个Python回溯都有几个重要的部分 。下图突出显示了各个部分:
回溯 什么是Python回溯? Traceback

文章插图
 
在Python中,最好从底部往上阅读回溯:
  1. 蓝色框: 回溯的最后一行是错误消息行 。它包含捕获的异常名称 。
  2. 绿色框: 异常名称之后是错误消息 。此消息通常包含有助于理解引发异常的原因的信息 。
  3. 黄色框: 在回溯的上端,各种函数调用从底部移动到顶部,从最近的函数调用到最远的函数调用 。这些调用的每一个调用都由两行条目表示 。每个调用的第一行包含文件名、行号和模块名等信息,这些信息都指定了代码的位置 。
  4. 红色下划线: 这些调用的第二行包含实际被执行的代码 。
当你在命令行中执行代码和在REPL中运行代码时,回溯输出会有一些不同 。下面是在REPL中执行的与上一节相同的代码以及执行后产生的回溯输出:
回溯 什么是Python回溯? Traceback

文章插图
 
注意用 "<stdin>"替代文件名的地方 。这是有意义的,因为你是通过标准输入来输入代码的 。而且,执行的代码行不会显示在回溯中 。
注意: 如果你经常在其他编程语言中查看回溯,那么你会注意到它与Python的回溯方式相比有一个主要不同 。大多数其他语言在顶部打印异常,然后从顶部到底部,从最近的调用到最远的调用 。
前面已经说过,但这里还是要重申一下,你应该从底部到顶部来阅读Python回溯 。这是非常有用的,因为回溯会被打印出来,而你的终端(或你正在阅读回溯的任何地方)通常会在输出的底部结束,这为你提供了开始阅读回溯的最佳位置 。
具体的回溯浏览
浏览一些具体的回溯输出,可以帮助你更好地理解并查看回溯将为你提供什么信息 。
下面代码被用在例子中来说明Python回溯为你提供的信息:
回溯 什么是Python回溯? Traceback

文章插图
 
在这里,who_to_greet()接受一个值person,并返回它或提示输入一个值返回来代替 。
然后,greet()接受一个要打招呼的名字someone和一个可选的greeting值,并传入someone值来调用print(). who_to_greet() 。


推荐阅读