首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

0基础学Python之二十五:异常处理(下)

Hi 大家好,我是王可乐,欢迎回到我们的零基础学 Python 课程。上一节课里,可乐为大家介绍了什么是异常,以及如何识别、定位异常和寻找异常的解决办法。在编写代码时,我们应该尽量避免出现异常。

不过,很多时候异常的发生也是不可避免的,特别是程序运行时需要读取用户输入的时候。和很多其他语言一样,Python 提供了一个异常的处理框架,可以用来对可能发生的异常进行预判和防护。这一节课里,可乐就来为大家介绍一下 Python 中的异常处理。

我们先来看一下,在第二课中为大家介绍的小游戏代码。

这段代码的第 8 行中,我们调用了 Python 内置的 input() 函数,并且提示用户在这里输入一个 1 到 100 之间的整数。用户输入之后,input() 函数返回用户输入的字符串,随后我们用 int() 函数将用户输入的字符串转换成一个整数。看起来没有问题。不过,假如用户没有输入整数,而是随便输入了一个其他字符串呢?我们把这段代码拿出来,用 Python Shell 演示一下:

可以看到,int() 函数抛出了一个叫做 ValueError 的异常,提示我们字符串 'abc' 不能被转换成十进制的整数。由于我们没有对异常做任何处理,在这个小游戏里,如果用户不小心输入了非 0 到 9 之间的字符,那么游戏程序就会抛出这个异常而退出。

我们可以检查用户的输入,判断用户是否输入了合法的字符,在输入合法的时候才将用户输入转换为整数。例如,可以这样来写代码:

这里,is_decimal() 需要我们自己实现,我们既可以用一个 for 循环检查输入字符串中的每一个字符,看看是否位于 ASCII 码的数字范围,也可以用以后将要学习到的正则表达式。

在日常写代码中,有很多类似的异常情况需要我们去考虑。特别是当我们面对用户输入的时候,如果我们盲目信任用户的输入,那么不仅可能造成程序崩溃、结果错误,甚至,当我们的代码在网络上运行时,还会引发许多安全问题,使得我们暴露在骇客的攻击之下。

在编码过程中对各种异常情况的防范处理,我们称作防御性编程。有很多资料为大家提供了防御性编程的介绍、建议等,建议同学们搜索学习一下,为安全编程打下意识基础。

上面的代码里,我么使用了 IF 语句来对用户输入进行了额外的判断。实际上,使用 Python 的异常处理功能,能够更加简单优雅地解决这个问题。我们还是先来看例子:

这段代码里,使用了 Python 的 try 和 except 关键字。这个语句的意思可以理解为:尝试运行 try 关键字后面的语句,如果代码运行没有问题,那么语句运行结束;如果代码抛出了 ValueError 异常,那么就执行 except 后面的语句。

在我们游戏代码的循环语句中,我们可以使用类似的代 码包裹用户输入的语句,并且在 except 后面的语句块中加一句 continue。这样,在用户输入错误抛出异常时,我们就结束当前循环的运行,进入下一次循环,让用户重新输入。大家可以自己尝试改写一下,或者拷贝可乐代码仓库中的代码,试一下看是不是游戏体验好了很多呢?

上面这种代码叫做异常的捕获处理。使用异常捕获,捕获了异常之后,通常我们会提示用户、记录日志,或者改变代码执行流程,就像上面的 continue 语句一样。和 IF 语句的 ELIF 子句类似,except 子句也可以重复多次;此外,和 IF 语句的 ELSE 子句类似,可以在 try 语句的最后使用 finally 关键字,Python 则会保证 finally 语句块中的代码总是会被运行;

try 语句自己也支持 else 子句,这里的代码则在没有异常出现的时候总是会运行。我们来看下面的例子:

这段代码里的 是一个特殊的异常,它会在用户按 Ctrl-C 组合键的时候发生。

这里,我们按下 Ctrl-C。可以看到,代码提示我们"输入中断",这表示代码成功捕获了 KeyboardInterrupt 这个异常;此外,我们看到"这句话总是被执行"也打印了出来。

我们再来试一下,这一次我们输入 abc,触发 ValueError。可以看到,代码提示我们输入错误,并且这时也执行了 finally 子句。

最后,我们输入一个正确的数字 42 试一下。大家可以看到,else 子句被执行了,这个子句只会在我们输入正确,没有触发异常的时候运行。

此外,finally 子句也运行了,这就是 finally 关键字的作用,它在无论何种异常情况下都能执行。这个特性在做一些清理工作,例如关闭文件、缓存、数据库连接等方面尤其有用。

我们上面这种写法,用 except 语句捕获并处理了不同的异常,实现了不同的异常情况区别对待的功能。

假如说有若干个异常情况可以做同样的处理,except 也是可以同时捕获多种不同类型异常的,写法类似 except (XXXError, YYYError, ZZZError): ;

此外,except 后面也可以不写任何异常类型,这时 except 就会尝试捕获所有发生的异常。不过,可乐不建议大家盲目地捕获所有的异常,一方面是这样我们可能掩盖了代码中的严重错误;另一方面,盲目捕获所有异常也是一种偷懒的做法,总是这么做,你就没有动力研究各种可能发生的异常了。

最后,except 语句还支持用 as 关键字将捕获的异常赋值给一个变量;捕获的异常处理之后还可以使用 raise 语句抛出;并且,我们也能够定义自己的异常类型。

好了,今天的课程可乐就先讲到这里。写代码难免遇到错误和异常,而在大型代码中异常处理更是尤为重要。在使用内置函数、第三方库时,大家可以多查阅文档,看看别人写的函数是否会抛出异常,又会抛出什么样的异常,需要做什么样的处理。希望大家以后在写代码的时候,都能认真思考,勤于调研,写出不倒翁一样稳定的代码哦。

我们对异常处理的介绍先到这里。下一节课将会是我们初级课程的最后一课,可乐会利用我们前面学习到的各种知识,带领大家写一个更加好玩,可订制的小游戏,敬请期待哦。

如果你喜欢我们的课程,欢迎关注我们的公众号“可乐编程”,同时也请转发给你的朋友们哦。可乐感谢大家的支持,我们下次课再见!

往期课程:

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

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

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

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

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券