10.1 什么是异常

10.1.1 错误

在深入介绍异常之前,我们来看看什么是错误。从软件方面来说,错误是语法或是逻辑上的。语法错误指示软件的结构上有错误,导致不能被解释器解释或编译器无法编译。这些错误必须在程序执行前纠正。

当程序的语法正确后,剩下的就是逻辑错误了。逻辑错误可能是由于不完整或是不合法的输入所致;在其他情况下,还可能是逻辑无法生成、计算、或是输出结果需要的过程无法执行。这些错误通常分别被称为域错误和范围错误。

当Python检测到一个错误时,解释器就会指出当前流已经无法继续执行下去。这时候就出现了异常。

10.1.2 异常

对异常的最好描述是:它是因为程序出现了错误而在正常控制流以外釆取的行为。这个行为又分为两个阶段:首先是引起异常发生的错误,然后是检测(和釆取可能的措施)阶段。

第一个阶段是在发生了一个异常条件(有时候也叫做例外的条件)后发生的。只要检测到错误并且意识到异常条件,解释器会引发一个异常。引发也可以叫做触发,抛出或者生成。解释器通过它通知当前控制流有错误发生。Python也允许程序员自己引发异常。无论是Python解释器还是程序员引发的,异常就是错误发生的信号。当前流将被打断,用来处理这个错误并釆取相应的操作。这就是第二阶段。

对异常的处理发生在第二阶段,异常引发后,可以调用很多不同的操作。可以是忽略错误(记录错误但不采取任何措施,采取补救措施后终止程序),或是减轻问题的影响后设法继续执行程序。所有的这些操作都代表一种继续,或是控制的分支。关键是程序员在错误发生时可以指示程序如何执行。

你可能已经得出这样一个结论:程序运行时发生的错误主要是由于外部原因引起的,例如非法输入或是其他操作失败等。这些因素并不在程序员的直接控制下,而程序员只能预见一部分错误,编写常见的补救措施代码。

类似Python这样支持引发和处理异常(这更重要)的语言,可以让开发人员可以在错误发生时更直接地控制它们。程序员不仅仅有了检测错误的能力,还可以在它们发生时采取更可靠的补救措施。由于有了运行时管理错误的能力,应用程序的健壮性有了很大的提高。

异常和异常处理并不是什么新概念。它们同样存在于Ada、Modula-3、C++、Eiffel和Java中。异常的起源可以追溯到处理系统错误和硬件中断这类异常的操作系统代码。在1965年左右,PL/1作为第一个支持异常的主要语言出现,而异常处理是作为一个它提供的软件工具。和其他支持异常处理的语言类似,Python采用了“尝试(try)”块和“捕获(catching)”块的概念,而且它在异常处理方面更有”纪律性”。我们可以为不同的异常创建不同的处理器,而不是盲目地创建一个“捕获所有(catch-all)”的代码。