![Python高效开发实战:Django、Tornado、Flask、Twisted(第3版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/109/40795109/b_40795109.jpg)
1.5 异常
异常处理是编程语言中的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件)。在当前主流编程语言的错误处理机制中,异常处理已经逐步代替了error code错误的处理方式,异常处理分离了接收和处理错误代码。这个功能使开发者理清了思绪,也增强了代码的可读性,方便了维护者阅读和理解。
1.5.1 异常处理
异常处理(又称为错误处理)功能提供了处理程序运行时出现的任何意外或异常情况的方法。Python异常处理使用try、catch、else和finally关键字来尝试可能未成功的操作、处理失败及正常情况,以及在事后清理资源。Python异常捕捉及处理的常用语法如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/068-1.jpg?sign=1739269551-4jTZPBIAeZjnxi9wSsWRJuSzGKCYCdyz-0-71c6b1ebc62878e9991cc5151990bc2d)
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/069-1.jpg?sign=1739269551-BPnmaqcXbo1578yWhmzJWMoaPgcYsUre-0-7f6c34538810aa45f20653157b9467d5)
语法规则较复杂,对其解释如下。
• 可能产生异常的代码需要写在try块中。在执行过程中一旦try块发生异常,则try块剩余的代码会被终止执行。
• except块用于定义当某种异常发生时所要执行的代码。except有5种具体形式:第1种形式是except指定当某种异常发生时,执行其块内的代码;第2种形式是一条except语句可以捕获多种异常;第3种形式是捕获的异常可以被转换为一个变量variance;第4种形式是可以捕获多种异常并转换为变量;第5种形式是捕获任何异常。
• 每种except形式都可以被定义多次,当try块中发生异常时,系统从上到下逐个检查except块。当发现满足发生异常定义的except块时,进入该except块进行异常处理,并且其他except块被忽略。
• else是可选块,用于定义当try块中的代码没有发生异常时所要做的处理。
• finally是可选块,无论try块中是否有异常发生,其中的代码都会被执行。
【示例1-31】异常处理的示例代码如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/069-2.jpg?sign=1739269551-QaMwUOBk5dmdAsyS8rhVb6kldp5KtODZ-0-e33e85ee2014138062e1dc5a61b78d31)
算术中0作为除数没有意义,所以上述try块中的第1行代码将产生ZeroDivisionError异常,该异常会在except块中被捕获。该代码的执行结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/069-3.jpg?sign=1739269551-NecNIy29gFh1GcAKjDnmE10nn36wgGHl-0-88f8f5cd01589cf189b9174e68b52613)
【示例1-32】多个except块捕获异常的示例代码如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/070-1.jpg?sign=1739269551-l1udeW4mH2BqZOwqutbLrkYKGaau2Mg2-0-6bb73e8f715d9b6de9664a70a79de514)
try块中先定义了一个列表myList,然后尝试打印myList中的index为10的元素,但是因为myList中只有两个元素,所以会引发IndexError异常。该异常被第2个except块所捕获,代码执行结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/070-2.jpg?sign=1739269551-FrSscQ5qpmj44rdqWcBjNygEfkXCQ8vr-0-171786ed8b83c0d2a70eeed83d8b0942)
1.5.2 自定义异常
除了系统预定义的异常(比如之前例子中出现的IndexError、ZeroDivisionError等),开发者还可以定义自己的特定逻辑异常。自定义异常的编程方法是建立一个继承自系统异常的子类,并且在需要引发该异常时用raise语句抛出该异常。
【示例1-33】自定义异常代码演示如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/070-3.jpg?sign=1739269551-g6kextKaMNn6nJLcifvTgezhZaTeO5Vn-0-8df5c2276deddd8568eb9bdf1afc1a36)
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/071-1.jpg?sign=1739269551-tdf00n80qziJsh4w496bnijNcmuDimYt-0-f59c7ee01a31f048ef911d524f3ce9d4)
本例定义了一个异常类MyError,异常类的__str__()函数可以用于设置本异常的字符串表达方式。主函数main()判断是否在启动程序时输入了命令行参数,如果没有输入参数则用raise关键字引发MyError异常。将该代码保存到文件except3.py中,执行结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/071-2.jpg?sign=1739269551-xY41icmJSBxDcQjHO6tC5gOWzJPfBEHZ-0-8c36d6ef446c5de93cf010dcc800d474)