文件与异常(三)

异常

Python使用被称为异常的特殊对象来管理程序执行期间发生的错误。每当发生让Python不知 所措的错误时,它都会创建一个异常对象。如果你编写了处理该异常的代码,程序将继续运行; 如果你未对异常进行处理,程序将停止,并显示一个traceback,其中包含有关异常的报告。

异常是使用try-except代码块处理的。try-except代码块让Python执行指定的操作,同时告 诉Python发生异常时怎么办。使用了try-except代码块时,即便出现异常,程序也将继续运行: 显示你编写的友好的错误消息,而不是令用户迷惑的traceback。

使用 try-except 代码块

当你认为可能发生了错误时,可编写一个try-except代码来处理可能引发的异常。你让 Python尝试运行一些代码,并告诉它如果这些代码引发了指定的异常,该怎么办。

try 语句有两种主要形式: try-except 和 try-finally . 这两个语句是互斥的, 也就是说你 只能使用其中的一种. 一个 try 语句可以对应一个或多个 except 子句, 但只能对应一个 finally 子句, 或是一个 try-except-finally 复合语句。

处理ZeroDivisionError异常的try-except代码 类似于下面这样:

我们将导致错误的代码行print(5/0)放在了一个try代码中。如果try代码中的代码运行起来没有问题,Python将跳过except代码; 如果try代码中的代码导致了错误,Python将查找这样的except代码块,并运行其中的代码,即其中指定的错误与引发的错误相同。

在这个示例中,try代码中的代码引发了ZeroDivisionError异常,因此Python指出了该如何解决问题的except代码块,并运行其中的代码。这样,用户看到的是一条 好的错误消息,而不是traceback:

如果try-except代码后面还有其他代码,程序将接着运行,因为已经告诉了Python如何处理这种错误。

使用异常避免崩溃

发生错误时,如果程序还有工作没有完成,妥善地处理错误就尤其重要。这种情况经常会出现在要求用户提供输入的程序中;如果程序能够妥善地处理无效输入,就能再提示用户提供有效输入,而不至于崩溃。

下面来创建一个只执行除法运算的简单计算器:

在第6行,这个程序提示用户输入一个数字,并将其存储到变量first_number中; 如果用户输入的不是表示退出的q,就再提示用户输入一个数字,并将其存储到变量second_number中(见第9行 )。 接下来,我们计算这两个数字的商 (即answer,见12行)。这个程序没有采取任何处理错误的措施,因此让它执行除数为0的除法运算时,它将崩溃:

程序崩溃可不好,但让用户看到 traceback 也不是好主意。不懂技术的用户会被它们搞糊涂, 而且如果用户 怀有恶意,他会通过traceback获悉你不希望他知道的信息。例如,他将知道你的程序文件的名称,还将看到部分不能正确运行的代码。有时候,训练有素的攻击者可根据这些信息判断出可对你的代码发起什么样的攻击。

else 代码块

通过将可能引发错误的代码放在try-except代码中,可提高这个程序抵御错误的能力。错误是执行除法运算的代码行导致的,因此我们需要将它放到try-except代码块中。这个示例还包含一个else代码块; 依赖于try代码块成功执行的代码都应放到else代码中:

我们让Python尝试执行try代码块中的除法运算(见12行),这个代码块只包含可能导致错误的代码。依赖于try代码块成功执行的代码都放在else代码中; 在这个示例中,如果除法运算成功,我们就使用else代码块来打印结果(见16行)。

except代码块告诉Python,出现ZeroDivisionError异常时该怎么办(见14行 )。如果try代码因除零错误而失败,我们就打印一条友好的消息,告诉用户如何避免这种错误。程序将继续运行,用户根本看不到traceback:

try-except-else代码块的工作原理大致如下: Python尝试执行try代码块中的代码; 只有可能引发异常的代码才需要放在try语句中。有时候,有一些仅在try代码块成功执行时才需要运行的的代码; 这些代码应放在else代码中。except代码块告诉Python,如果它尝试运行try代码块中的代码时引发了指定的异常,该怎么办。

通过预测可能发生错误的代码,可编写健壮的程序,它们即便面临无效数据或缺少资源,也能继续运行,从而能够抵御无意的用户错误和恶意的攻击。

失败时不提示

使用 pass

决定报告那些错误

在什么情况下该向用户报告错误? 在什么情况下又应该在失败时不提示呢? 如果用户知道要分析哪些文件,他们可能希望在有文件没有分析时出现一条消息,将其中的原因告诉他们。 如果用户只想看到结果,而并不知道要分析哪些文件,可能就无需在有些文件不存在时告知他们。 向用户显示他不想看到的信息可能会降低程序的可用性。Python的错误处理结构让你能够细致地控制与用户分享错误信息的程度,要分享多少信息由你决定。

编写得很好且经过详尽测试的代码不容易出现内部错误,如语法或逻辑错误,但只要程序依赖于外部因素,如用户输入、存在指定的文件、有网络连接,就有可能出现异常。凭借经验可判断该在程序的什么地方包含异常处理 ,以及出现错误时该向用户提供多少相关的信息。

finally子句

finally 子句是无论异常是否发生,是否捕捉都会执行的一段代码. 你可以将 finally 仅仅配合 try 一起使用,也可以和 try-except(else 也是可选的)一起使用. 你可以用 finally 子句 与 try-except 或 try-except-else 一起使用。

下面是 try-except-else-finally 语法的示例:

当然,无论如何,你都可以有不止一个的 except 子句,但最少有一个 except 语句,而 else 和 finally 都是可选的. A,B,C 和 D 是程序(代码块). 程序会按预期的顺序执行.(注意:可能的顺序是 A-C-D[正常]或 A-B-D[异常]).无论异常发生在 A,B,和/或 C 都将执行 finally 块。

常见的异常

本文来自企鹅号 - YESLAB媒体

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏社区的朋友们

在共享内存实现 Redis(下)

从实现方式入手,设计了一种综合二者优点的方案:将 Redis 做成数据逻辑分离,数据存放共享内存,进程只负责存储逻辑,同时解决 Redis 长命令卡顿和 for...

45400
来自专栏WD学习记录

8-21Android 学习ing

(2)Tomcat服务器默认采用的是ISO8859-1编码得到的参数值,这种编码不支持中文,也会导致乱码

10830
来自专栏java 成神之路

vmstat 命令详解

48070
来自专栏企鹅号快讯

python-IDLE清屏和标记行数,其他推荐

——python—— 自定义IDLE清屏键 将网上下载的ClearWindow.py,放到python安装路径的lib\idlelib文件夹中,然后在这个文件夹...

30270
来自专栏性能与架构

console.log() 之外的调试技巧

console.log( ) 是JS开发时常用的小工具,输出一些信息来辅助调试,console 还有很多有用的方法,下面介绍几个方便调试的用法 跟踪堆栈 例如想...

38390
来自专栏Coco的专栏

【前端安全】JavaScript防http劫持与XSS

1.1K40
来自专栏前端知识分享

第217天:深入理解Angular双向数据绑定的原理

双向绑定是新的前端框架中频繁出现的一个新词汇,也是mvvm的核心原理。angularjs五条核心信念中的数据驱动,便是由双向绑定进行完成。

19720
来自专栏开源优测

RobotFramework怎么写好用例

github地址:https://github.com/robotframework/HowToWriteGoodTestCases/blob/master/H...

30120
来自专栏会跳舞的机器人

java并发编程的艺术笔记第一章——并发编程的挑战

单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切...

11530
来自专栏PHP在线

PHP10个实用函数

介绍PHP中的10个实用函数 [导读] PHP的功能越来越强大,里面有着非常丰富的内置函数。资深的PHP程序员对它们可能都很熟悉,但很多的PHP学习者,仍然对...

37940

扫码关注云+社区

领取腾讯云代金券