0基础学Python之二十四:异常处理(上)

Hi 大家好,我是王可乐,欢迎回到我们的零基础学 Python 课程。学完了可乐前面的课程,相信大家已经对 Python 有了一个基本的认识和掌握。可乐也一直在鼓励大家跟着我们的课程进行实际操作练习,以熟悉和巩固学到的知识。

如果你的代码和数据没有问题,那么 Python 就可以帮你运行代码逻辑,得到结果。然而在实际练习和编码中,我们经常会遇到发生错误和异常的情况。例如在前面的课程中,我们遇到过语法错误、名字错误、类型错误、文件不存在错误等等。

很多时候,写代码出现错误是难免的。今天的课程里,可乐就开始为大家讲解一下 Python 中的错误;并且教大家发现错误、识别和定位错误原因,以及用防御性代码来处理错误。

我们先来看一下语法错误。我们说 Python 代码必须按照规定的语法来书写,否则就无法运行。例如,我们打开 Python Shell 输入:

出现了错误提示。我们看最后一行,可以看到,Python 告诉我们这里发生了一个语法错误,也就是 SyntaxError。然后,Python 用一个向上的小箭头指向了我们语句中出错的地方,告诉我们是在 world 一词的后面出现的错误;并且,SyntaxError 冒号后面的错误提示说:在扫描字符串时遇到了 EOL。

这里,EOL 是 End Of Line 的缩写。因此这个提示的意思就是,Python 正在扫描处理字符串时,错误遇到了一个行尾。可乐前面讲过,正常的语法里,双引号包裹的字符串是不能跨行的,除非行尾换行符用转义字符反斜线转义。因此,通过认真阅读 Python 的错误提示,我们就可以快速找到出错的地方。

此外,这个错误提示第一行 File stdin, line 1 ,其实是向我们说明了出错代码的文件名和行号。这里,由于可乐在是 Python Shell 里演示的出错语句,因此文件名显示是 stdin,它叫做标准输入。这就是说,出错的是可乐刚刚从键盘输入到 Shell 上的代码;由于 Shell 总是从一个新的三大于号符号开始计算行号,因此这里显示行号为一。如果我们写一个 Python 脚本,里面发生了语法错误,那么 Python 就会显示这个脚本文件的名字,以及出错代码的真正行号了。大家可以自己试一试哦。

语法错误一般比较容易发现,也比较容易解决。更多的时候,尽管代码的语法没有问题,但是运行起来也会发生错误。我们把这种语法正确,但运行时发生的错误称作异常,就是英文的 Exception。实际上,异常是我们写代码时遇到的主要错误类型。

我们先来看几个异常的例子,这几个例子都来自 Python 的官方文档。

我们看到,这三行代码出现了三种不同的异常,分别是 ZeroDivisionError, NameError, 和 TypeError,这三个名字叫做异常的类型。Python 把程序运行中可能出现的异常按照类型来归类,方便后续对异常的统一处理。实际上,每一个异常的类型都是一个叫做"类"的东西,由于我们的初级课程还没有涉及面向对象编程的有关知识,可乐就不展开讲解了。

异常类型之后,冒号后面,打印的是一行提示性的文字,它们一般提示了异常出现的原因。例如,第一个异常是我们把 0 当作了除数;第二个异常是 spam 这个名字没有定义;最后一个异常则是由于加号前面是字符串,因此后面也必须使用字符串类型而不是整数类型。

和前面的语法错误类似,Python 也指出了错误发生时的文件和行号等信息,此外,还有一个错误发生的上下文信息,这里是 ,以及错误的 Traceback 信息。什么是 Traceback 和上下文信息呢?我们来看一个例子。首先,我们在 C:\colecode\ 目录下新建一个 Python 文件,命名为 test_err.py:

保存文件内容,然后我们打开 cmd 终端,cd 切换到 C:\colecode\,然后输入 python 空格 test_err.py,回车。

可以看到,代码报了一个除 0 的错误。并且提示了两个出错的地方,分别是文件的第二行和第四行。什么意思呢?实际上这里的两个出错的地方展示了代码的调用关系,而 Traceback 就是沿调用关系回溯的意思。这个出错信息应该自上而下这么来阅读:

首先,出错的地方在第四行,我们看到,这行代码调用了 devide() 函数;

然后,在 devide 函数的内部,实际上是代码第二行该函数的 return 语句之处报了错;

那么报了什么错呢,除零错误;

这样,我们就找到了错误的原因。当然,我们这里的例子只有两个层级,错误也比较简单,如果遇到比较复杂的调用关系,就需要大家仔细追溯代码逻辑,慢慢来寻找问题所在了。这时,这里的 Traceback 信息就是一个非常有用的线索了。

此外,我们还看到,上述错误提示信息的行号后面还有一个 in 某某地方的提示。这个提示叫做上下文提示,例如上面例子的第二行,就提示这里位于函数 devide 内部;而第四行的 in 后面是 module,这个符号其实就是表示错误发生在代码的最外层。

除了我们前面见到过的这几个异常类型,Python 中还有相当多其他内置的异常类型。并且,Python 还支持自定义的异常类型,因此各种第三方模块、框架等也可能有自己独特的异常类型。

如果你以后编写自己的代码,不可避免的会遇到各种各样的异常。一般来说,遵循可乐上面提到的方法,都能够找到异常发生的原因,从而想办法解决它。如果你遇到了从来没有遇到过的异常,也不用担心,网络上有相当多的资源可以查询。例如 Python 的官方文档、牛客网社区、Stack Overflow 社区等国内外资源。在搜索引擎中搜索你遇到的异常信息,很多时候都能找到异常发生的原因和解决方案。

除了通过修改代码来解决异常,Python 还支持一种称作异常捕获的处理方式。不过,由于时间的关系,可乐今天就先讲到这里。

下一节课里,可乐会为大家介绍 Python 的异常捕获语法,并且为我们第二课的小游戏加入异常处理的功能,使它运行更加稳定。敬请期待哦。如果你喜欢我们的课程,欢迎关注我们的公众号“可乐编程”,同时也请转发给你的朋友们哦。可乐感谢大家的支持,我们下次课再见!

往期课程:

0基础学Python之二十三:JSON数据格式

《0基础学Python之二十二:文件操作(下)》

《0基础学Python之二十一:文件操作(上)》

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180602G0ET7K00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券