![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=1738898468-jzQm1NFrpj2jlanclBw7YC79Ciq8dEOa-0-5137952572474c2b7946d0a072034661)
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/069-1.jpg?sign=1738898468-RE4ZyCrUBiFeCRWC2acxJDUJGf2vNu5U-0-3f001754d323d34c8c357866390f9a8d)
语法规则较复杂,对其解释如下。
• 可能产生异常的代码需要写在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=1738898468-Ac2sCrSnO1HAzXDAjPa4c2wgKzIP3qJu-0-be36216b8271496e409e863b33bc643f)
算术中0作为除数没有意义,所以上述try块中的第1行代码将产生ZeroDivisionError异常,该异常会在except块中被捕获。该代码的执行结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/069-3.jpg?sign=1738898468-14mjvc0EbIAjOuZXPjjPDA6NQKAROXdS-0-5a14a72086a814eb366052c4d1d2a7fd)
【示例1-32】多个except块捕获异常的示例代码如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/070-1.jpg?sign=1738898468-NUQxDEfeqRuU0zCq0FwB1rgQyMG2Ct6V-0-231b8507483031c8f8624bb3386f5aff)
try块中先定义了一个列表myList,然后尝试打印myList中的index为10的元素,但是因为myList中只有两个元素,所以会引发IndexError异常。该异常被第2个except块所捕获,代码执行结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/070-2.jpg?sign=1738898468-niYRpP30VXxyItdNDwb5FcmetPlQpMn5-0-9f36bbd34a092591ee541a413c215333)
1.5.2 自定义异常
除了系统预定义的异常(比如之前例子中出现的IndexError、ZeroDivisionError等),开发者还可以定义自己的特定逻辑异常。自定义异常的编程方法是建立一个继承自系统异常的子类,并且在需要引发该异常时用raise语句抛出该异常。
【示例1-33】自定义异常代码演示如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/070-3.jpg?sign=1738898468-QEtxUv8UcOMQEIYL4HGKLwOShYK1qhUX-0-804d0e390d558f6c18c257b1d5c77b9b)
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/071-1.jpg?sign=1738898468-Tiuq6ltkNetladb4r3XW13oIwMYbrAWL-0-0b0513b4b38ac405c0cc945d4cc5c1de)
本例定义了一个异常类MyError,异常类的__str__()函数可以用于设置本异常的字符串表达方式。主函数main()判断是否在启动程序时输入了命令行参数,如果没有输入参数则用raise关键字引发MyError异常。将该代码保存到文件except3.py中,执行结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/071-2.jpg?sign=1738898468-OHJaszRutgoNMLagWdwpGHigxlDK7QO2-0-f6c127db4e8c0193ea33a485242889e3)