《数据结构与算法:Python语言描述》一2.4Python异常

2.4Python异常

现在简单介绍Python异常与类的关系,语言内建的异常类层次结构,以及Python语言如何利用面向对象的观点组织异常处理过程。编程中有时需要自己定义异常(类型),如果需要这样做,就应该选一个系统异常类,从它派生。

2.4.1异常类和自定义异常

异常是Python语言中的一套特殊的控制机制,主要用于支持错误的检查和处理,也可以用于实现特殊的控制转移。如果程序执行中发生异常,无论是解释器发现的异常情况(例如除零或类型错误等),还是通过raise语句引发的异常,正常执行控制流立刻终止,解释器转入异常处理模式,查找能处理所发生异常的处理器。如果找不到相应的异常处理器,在交互解释环境下,系统将在环境中输出错误信息,结束当前执行并回到系统的交互状态,等待下一输入。在直接执行方式下,当前程序直接终止。
程序运行中发生的每个异常都有特定的名字,如ValueError、TypeError、ZeroDivision-Error等,解释器根据发生的异常去查找处理器。Python里处理异常的结构是try语句。每个try语句可以带有任意多个except子句,这种子句就是异常处理器,子句头部用一个表达式描述它捕捉和处理的异常。
实际上,Python的异常都是类(class),运行中产生异常就是生成相应类的实例对象,异常处理机制完全基于面向对象的概念和性质。全体内部异常类构成了一个树形结构,所有异常类的基类是BaseException,其最主要的子类是Exception,内置异常类都是这个类的直接或间接派生类。如果用户需要定义异常,就应该从系统异常类中选择一个合适的异常,从它派生出自己的异常类。例如:

class RationalError(ValueError):
    pass

最简单的情况(很常见)只是希望定义一种特殊异常,并不需要这种异常有什么特殊功能(如上即是)。在这种情况下,选一个系统异常类派生自己的异常类,类体不需要定义任何属性。但为了语法完整,可以在这里写一个pass语句。
如果运行中发生异常,查找相应处理器的工作由解释器完成,这里的工作方式也基于对象和类的关系。在一个except子句头部可以列出一个或多个异常名(一般说,是表示异常类的表达式),列出多个异常名时需要采用括号括起的元组形式。列在except子句头部的异常名表示本异常处理器准备捕捉和处理的异常。
运行中发生的异常与处理器的匹配按面向对象的方式处理。假设运行中发生的异常是e,如果一个异常处理器头部列有异常名E,且isinstance(e,E)为真,那么这个处理器就能捕捉并处理异常e。举例说,如果运行中引发了一个RationalError异常,某个处理器头部列出了RationalError,或者ValueError,或者Exception,该处理器都能捕捉这个异常。当然,匹配ValueError的处理器还能捕捉和处理其他异常,匹配Exception的处理器能捕捉和处理各种主要异常。

2.4.2异常的传播和捕捉

运行中的异常可能发生在模块层面的语句的执行中,更多情况是发生在某个函数的执行中。假设在函数f的执行中发生异常e,当前执行立即中断,解释器转入异常处理模式,设法找到处理e的处理器。有关查找过程如下:
首先在发生异常的函数体里查找处理器:
如果发生异常的语句位于一个try语句体里,首先顺序检查这个try语句后部的各except子句,检查是否存在能处理e的处理器。
如果发生异常的try语句的所有异常处理器都不能处理e,解释器转去查看包围着该try语句的外围try语句(如果存在),检查是否存在能与e匹配的异常处理器。这个查找过程将在e发生的函数f里逐层进行。
如果e不能在函数f里处理,f的执行异常终止,e在函数f这次执行的调用点重新引发,导致又一轮处理器查找工作。查找规则与上面一样。
如果上面查找过程在某一步找到了与e匹配的处理器,解释器就转去执行该except子句的体(异常处理器代码)。执行完这段代码后,解释器回到正常执行模式,从该异常处理器所在的try语句之后继续执行。
上述查找过程可能导致函数一层层以异常方式退出,有可能一直退到当前模块的最上层也没有找到与之匹配的处理器:
如果程序是在解释器的交互方式下执行,Python解释器终止该模块执行并回到交互状态,输出错误信息后等待用户的下一个命令。
如果程序是自主执行(或称按批处理方式执行),该程序立即终止。
如果异常发生在主模块的表层(不在任何函数里),处理过程同样如上所述。
在异常处理过程中还可能出现一些情况。例如,正在执行处理器代码时又发生了新异常;或者处理中遇到某些特殊情况,需要引发新的异常。Python语言里还有关于这些情况的细节规定,这里就不继续讨论了。

2.4.3内置的标准异常类

Python语言定义了一套标准异常类,它们都是BaseException的派生类,其最重要子类是Exception,标准异常类都是Exception的直接或间接派生类。
下面是一些常见异常,后面有些例子从其中一些异常派生自己的异常类:

BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
     +-- ArithmeticError
     |    +-- FloatingPointError
     |    +-- OverflowError
     |    +-- ZeroDivisionError
     +-- AssertionError
     +-- AttributeError
     +-- EOFError
     +-- ImportError
     +-- LookupError
     |    +-- IndexError
     |    +-- KeyError
     +-- NameError
     |    +-- UnboundLocalError
     +-- OSError
     |    +-- BlockingIOError
     |    +-- ChildProcessError
     |    +-- ConnectionError
     |    |    +-- BrokenPipeError
     |    |    +-- ConnectionAbortedError
     |    |    +-- ConnectionRefusedError
     |    |    +-- ConnectionResetError
     |    +-- FileExistsError
     |    +-- FileNotFoundError
     |    +-- InterruptedError
     |    +-- IsADirectoryError
     |    +-- NotADirectoryError
     |    +-- PermissionError
     |    +-- ProcessLookupError
     |    +-- TimeoutError
     +-- ReferenceError
     +-- RuntimeError
     |    +-- NotImplementedError
     +-- SyntaxError
     |    +-- IndentationError
     |         +-- TabError
     +-- SystemError
     +-- TypeError
     +-- ValueError
     |    +-- UnicodeError
     |         +-- UnicodeDecodeError
     |         +-- UnicodeEncodeError
     |         +-- UnicodeTranslateError

这个图并不完全,还有一些被分类为“警告”(Warning)的异常等。

时间: 2024-10-27 13:01:34

《数据结构与算法:Python语言描述》一2.4Python异常的相关文章

《数据结构与算法:Python语言描述》一第1章 绪论

第1章 绪论 作为基于Python语言的"数据结构与算法"教程,本章首先讨论一些与数据结构和算法有关的基础问题,还将特别关注Python语言的一些相关情况. 1.1计算机问题求解 使用计算机是为了解决实际问题.计算机具有通用性,其本身的功能很简单,就是能执行程序,按程序的指示完成一系列操作,得到某些结果,或者产生某些效果.要想用计算机处理一个具体问题,就需要有一个解决该问题的程序.经过长期努力,人们已经为各种计算机开发了许多有用的程序.在面对一个需要解决的问题时,如果恰好有一个适用的程

《数据结构与算法:Python语言描述》一1.3算法和算法分析

1.3算法和算法分析 本节集中讨论算法的问题,特别是算法的性质及其分析技术. 1.3.1问题.问题实例和算法 在考虑计算问题时,需要清晰地区分问题.问题实例和算法三个概念,并理解它们之间的关系,这就是本小节讨论的内容.三个基本概念考虑一个计算问题时,需要注意到三个重要概念:问题:一个问题W是需要解决(需要用计算求解)的一个具体需求.例如判断任一个正整数N是否为素数,求任一个方形矩阵的行列式的值等.虽然可以严格定义"问题"的概念,但在这里还是想依靠读者的直观认识.总而言之,现实世界中存在

《数据结构与算法:Python语言描述》一1.2 问题求解:交叉路口的红绿灯安排

1.2 问题求解:交叉路口的红绿灯安排 本节展示一个具体问题的计算机求解过程,以此说明在这种过程中可能出现的一些情况,需要考虑的一些问题,以及一些可能的处理方法. 交叉路口是现代城市路网中最重要的组成部分,繁忙的交叉路口需要用红绿灯指挥车辆通行与等待,正确的红绿灯调度安排对于保证交通安全.道路运行秩序和效率都非常重要.交叉路口的情况多种多样,常见形式有三岔路口.十字路口,也有较为少见的更复杂形式的路口.进一步说,有些道路是单行线,在中国的交叉路口还有人车分流和专门的人行/自行车红绿灯等许多情况,

《数据结构与算法:Python语言描述》一2.3类的定义和使用

2.3类的定义和使用 前面给出了两个有理数类的定义,帮助读者得到一些有关Python类机制的直观认识.本节将介绍Python类定义的进一步情况.本书中对类的使用比较规范,涉及的与Python类定义相关的机制不多,只需要有最基本的了解就可以学习后面内容.另一方面,本书的主题是数据结构和算法,并不计划全面完整地介绍Python语言的面向对象机制和各种使用技术.本节主要想给读者提供一些可参考的基本材料,因此,下面有关Python语言的相关介绍将限制在必要的范围内,供读者参考,不深入讨论.有关Pytho

《数据结构与算法:Python语言描述》一3.5表的应用

3.5表的应用 本节通过一个简单的例子展示表结构的使用.这里给出了同一个问题的几种不同实现,其中使用了不同的表结构. 3.5.1Josephus问题和基于"数组"概念的解法 Josephus问题是数据结构教材中一个常见的实例:假设有n个人围坐一圈,现在要求从第k个人开始报数,报到第m个数的人退出.然后从下一个人开始继续报数并按同样规则退出,直至所有人退出.要求按顺序输出各出列人的编号.本节考虑第一种解决方法:基于Python的list和固定大小的"数组"概念,也就是

《数据结构与算法:Python语言描述》一1.4数据结构

1.4数据结构 从程序输入和输出的角度看,用计算机解决问题,可以看作实现某种信息表示形式的转换.如图1.5所示,把以一种形式表示的信息(输入)送给程序,通过在计算机上运行程序,产生出以另一种形式表示的信息(输出).如果: 具体的"信息表示A"表达了需要求解的某个问题的实例. 得到的"信息表示B"表达了与这个实例对应的求解结果. 那么就可以认为,这个程序完成了该问题实例的求解工作. 为了能用计算机处理与问题有关的信息,就必须采用某种方式表示它,并将相应表示送入计算机.

《数据结构与算法:Python语言描述》一第3章 线 性 表

第3章 线 性 表 在程序里,经常需要将一组(通常是同为某个类型的)数据元素作为整体管理和使用,需要创建这种元素组,用变量记录它们,传进传出函数等.一组数据中包含的元素个数可能发生变化(可以加入或删除元素).在有些情况下,可能需要把这样一组元素看成一个序列,用元素在序列里的位置和顺序,表示实际应用中的某种有意义的信息,或者表示数据之间的某种关系.线性表(简称表)就是这样一组元素(的序列)的抽象.一个线性表是某类元素的一个集合,还记录着元素之间的一种顺序关系. 线性表是最基本的数据结构之一,在实际

《数据结构与算法:Python语言描述》一3.3链接表

3.3链接表 本节考虑线性表的另一种实现技术. 3.3.1线性表的基本需要和链接表 回忆一下线性表的定义,它就是一些元素的序列,维持着元素之间的一种线性关系.实现线性表的基本需要是: 能够找到表中的首元素(无论直接或者间接,这件事通常很容易做到). 从表里的任一元素出发,可以找到它之后的下一个元素. 把表元素保存在连续的存储区里(顺序表),自然能满足这两个需求,其中元素间的顺序关联是隐含的.但是,要满足这两种需求,并不一定需要连续存储元素.显然,对象之间的链接也可以看作一种顺序关联,基于它也可以

《数据结构与算法:Python语言描述》一2.5类定义实例:学校人事管理系统中的类

2.5类定义实例:学校人事管理系统中的类 作为本章内容的总结,现在考虑一个综合性的实例:为一个学校的人员管理系统定义所需的表示人员信息的类,它们都是数据抽象. 2.5.1问题分析和设计 学校里有两大类人员,即学生和教职工,他们都是需要在系统里表示的对象.分析这两类人员需要记录的信息,可以看到这里有一些值得注意的情况:与两类人员有关的信息中存在一些公共部分,又有各自的特殊情况: 首先,作为人员信息,无论学生或教职工都有姓名.性别.年龄等公共信息.另外,为了便于学校管理,学生应该有一个学号,教职工也