回溯 什么是Python回溯? Traceback( 四 )


SyntaxError
当你的代码中有不正确的Python语法时,就会引发SyntaxError 。Python文档定义了此异常何时被引发:
当解析器产生语法错误时引发 。
下面代码的问题是函数定义行末尾缺少一个冒号 。在Python%20REPL中,这个语法错误在按下回车键后会立即被引发:

回溯 什么是Python回溯? Traceback

文章插图
 
SyntaxError的错误消息行只告诉你代码的语法有问题 。查看上面的行可以得到问题所在的行,通常用a ^(插入符号)指向问题点 。这里,函数的def语句中缺少冒号 。
同样,使用SyntaxError回溯,常规的第一行Traceback (most recent call last:也丢失了 。这是因为当Python试图解析你的代码时,SyntaxError会被引发,而实际上这些行并没有被执行 。
TypeError
当你的代码试图对一个对象执行某些不能执行的操作时,例如试图将一个字符串相加到一个整数中,或者在一个没有定义其长度的对象上调用len(),TypeError就会被引发 。Python文档中定义了此异常何时被引发:
当一个操作或函数被应用于一个不合适类型的对象时引发 。
下面是TypeError被引发的几个示例:
回溯 什么是Python回溯? Traceback

文章插图
 
以上所有引发TypeError的示例都会产生一个包含不同消息的错误消息行 。每一条消息都能很好地告诉你哪里出了问题 。
前两个示例尝试将字符串和整数相加 。然而,它们有细微的不同:
  • 第一个试图将一个str加到一个int 。
  • 第二个试图将一个int 加到一个 str 。
错误消息行反映了这些不同 。
最后一个例子尝试在一个int上调用len() 。错误消息行告诉你不能对一个int类型执行此操作 。
ValueError
当对象的值不正确时,ValueError将被引发 。你可以将其视为一个IndexError,当索引值不在序列范围之内时会被引发,只不过ValueError用于更一般的情况 。Python文档中定义了此异常何时被引发:
当一个操作或函数接收到一个具有正确类型但值不合适的参数时引发,并且这种情况不能被一个更精确的异常(比如IndexError)描述 。
下面是ValueError被引发的两个例子:
回溯 什么是Python回溯? Traceback

文章插图
 
在这些例子中,ValueError错误消息行会准确地告诉你这些值存在什么问题:
  1. 在第一个示例中,你试图解压缩太多的值 。错误消息行甚至告诉你,你期望解压缩3个值,但是只得到了2个值 。
  2. 在第二个例子中,问题是你得到了太多的值,但没有足够的变量来解压缩它们 。
如何记录一个回溯?获得异常及其生成的Python回溯意味着你需要决定如何处理它 。通常,修复代码是第一步,但有时问题出在未预期的或不正确的输入上 。虽然在代码中提供这些情况很好,但有时通过记录回溯和执行其他操作来隐藏异常也很有意义 。
下面是一个更真实的代码示例,它需要让一些Python回溯保持静默 。本例使用了requests库 。你可以在Python的requests库(指南)中获取更多信息:
回溯 什么是Python回溯? Traceback

文章插图
 
这段代码运行得很好 。当你运行此脚本时,你将一个URL作为命令行参数提供给它,它将调用该URL,然后打印出HTTP状态码和响应中的内容 。甚至在响应是一个HTTP错误状态时,它也可以工作:
回溯 什么是Python回溯? Traceback

文章插图
 
但是,有时你的脚本提供的用于检索的URL不存在,或者主机服务器关闭 。在这些情况下,这个脚本现在就会引发一个未捕获的ConnectionError异常,并打印一个回溯:
回溯 什么是Python回溯? Traceback

文章插图
 
这里的Python回溯可能非常长,还会引发许多其他异常,最终导致ConnectionError被requests库本身引发 。如果你向上移动到最后的异常回溯,你就可以看到问题都是从我们的代码urlcall .py中的第5行开始的 。
如果你将非法行封装在一个try和except块中,那么捕获适当的异常将允许你的脚本继续处理更多的输入:
回溯 什么是Python回溯? Traceback

文章插图
 
上面的代码使用了一个带有try和except块的else子句 。如果你不熟悉Python的这一特性,那么请在Python Exceptions:An Introduction中查看else子句 。


推荐阅读