python学习之旅笔记总结:第八章、异常

         编写计算机程序时,通常能够区分正常和异常(不正常)情况。异常事件可能是错误(如试图除以零),也可能是通常不会发生的事情。为处理这些异常事件,可在每个可能发生这些事件的地方都使用条件语句。例如,对于每个除法运算,都检查除数是否为零。然而这样做不仅效率低下、缺乏灵活性,还可能导致程序难以卒读。你可能很想忽略这些异常事件,希望它们不会发生,但Pythoon提供功能强大的替代解决方案——异常处理机制。

1 异常是什么

            Python使用异常对象来表示异常状态,并在遇到错误时引发异常。异常对象未被处理(或捕获)时,程序将终止并显示一条错误消息(traceback) 

           如果异常只能用来显示错误消息,就没多大意思了。但事实上,每个异常都是某个类(这里是ZeroDivisionError)的实例。你能以各种方式引发和捕获这些实例,从而逮住错误并采取措施,而不是放任整个程序失败

                        

2 让事情沿你指定的轨道出错

            正如你看到的,出现问题时,将自动引发异常。先来看看如何自主地引发异常,还有如何创建异常,然后再学习如何处理这些异常

2.1 raise 语句

          要引发异常,可使用raise语句,并将一个类(必须是Exception的子类)或实例作为参数。将类作为参数时,将自动创建一个实例。下面的示例使用的是内置异常类Exception

          在第一个示例(raise Exception)中,引发的是通用异常,没有指出出现了什么错误。

          

         在第二个示例中,添加了错误消息you are a wrong thing

           

          

2.2 自定义的异常类

            如何创建异常类呢?就像创建其他类一样,但务必直接或间接地继承Exception(这意味着从任何内置异常类派生都可以)。因此,自定义异常类的代码类似于下面这样

               

3 捕获异常

          异常比较有趣的地方是可对其进行处理,通常称之为捕获异常。为此,可使用try/except语句。假设你创建了一个程序,让用户输入两个数,再将它们相除,如下所示:

                 

注意 异常从函数向外传播到调用函数的地方。如果在这里也没有被捕获,异常将向程序的最顶层传播。这意味着你可使用try/except来捕获他人所编写函数引发的异常

3.1 不用提供参数

          捕获异常后,如果要重新引发它(即继续向上传播),可调用raise且不提供任何参数

3.2 多个 except 子句

           

3.3 一箭双雕

            如果要使用一个except子句捕获多种异常,可在一个元组中指定这些异常,如下所示:

                 

3.4 捕获对象

        要在except子句中访问异常对象本身,可使用两个而不是一个参数。(请注意,即便是在你捕获多个异常时,也只向except提供了一个参数——一个元组。

        需要让程序继续运行并记录错误(可能只是向用户显示)时,这很有用。下面的示例程序打印发生的异常并继续运行:

                 

           在这个小程序中,except子句也捕获两种异常,但由于你同时显式地捕获了对象本身,因此可将其打印出来,让用户知道发生了什么情况。

3.5 一网打尽

              如果你就是要使用一段代码捕获所有的异常,只需在except语句中不指定任何异常类即可。          

        像这样捕获所有的异常很危险,因为这不仅会隐藏你有心理准备的错误,还会隐藏你没有考虑过的错误。这还将捕获用户使用Ctrl + C终止执行的企图、调用函数sys.exit来终止执行的企图等

        在大多数情况下,更好的选择是使用except Exception as e并对异常对象进行检查。这样做将让不是从Exception派生而来的为数不多的异常成为漏网之鱼,其中包括SystemExit和KeyboardInterrupt,因为它们是从BaseException(Exception的超类)派生而来的。         

3.6 万事大吉时

         在有些情况下,在没有出现异常时执行一个代码块很有用。为此,可像条件语句和循环一样,给try/except语句添加一个else子句

         

3.7 最后

             最后,还有finally子句,可用于在发生异常时执行清理工作。这个子句是与try子句配套的

             

             finally子句非常适合用于确保文件或网络套接字等得以关闭

4 异常和函数

         异常和函数有着天然的联系。如果不处理函数中引发的异常,它将向上传播到调用函数的地方。如果在那里也未得到处理,异常将继续传播,直至到达主程序(全局作用域)。如果主程序中也没有异常处理程序,程序将终止并显示栈跟踪消息

5 异常之禅

          异常处理并不是很复杂。如果你知道代码可能引发某种异常,且不希望出现这种异常时程序终止并显示栈跟踪消息,可添加必要的try/except或try/finally语句(或结合使用)来处理它

6 不那么异常的情况

            如果你只想发出警告,指出情况偏离了正轨,可使用模块warnings中的函数warn

           

           如果其他代码在使用你的模块,可使用模块warnings中的函数filterwarnings来抑制你发出的警告(或特定类型的警告),并指定要采取的措施,如"error"或"ignore"

            

             

           如你所见,引发的异常为UserWarning。发出警告时,可指定将引发的异常(即警告类别),但必须是Warning的子类。如果将警告转换为错误,将使用你指定的异常。另外,还可根据异常来过滤掉特定类型的警告

7 小结

 异常对象:异常情况(如发生错误)是用异常对象表示的。对于异常情况,有多种处理方式;如果忽略,将导致程序终止

 引发异常:可使用raise语句来引发异常。它将一个异常类或异常实例作为参数,但你也可提供两个参数(异常和错误消息)。如果在except子句中调用raise时没有提供任何参数,它将重新引发该子句捕获的异常

 自定义的异常类:你可通过从Exception派生来创建自定义的异常

 捕获异常:要捕获异常,可在try语句中使用except子句。在except子句中,如果没有指定异常类,将捕获所有的异常。你可指定多个异常类,方法是将它们放在元组中。如果向except提供两个参数,第二个参数将关联到异常对象。在同一条try/except语句中,可包含多个except子句,以便对不同的异常采取不同的措施

 else子句:除except子句外,你还可使用else子句,它在主try块没有引发异常时执行。
 finally:要确保代码块(如清理代码)无论是否引发异常都将执行,可使用try/finally,并将代码块放在finally子句中

 异常和函数:在函数中引发异常时,异常将传播到调用函数的地方(对方法来说亦如此)。
 警告:警告类似于异常,但(通常)只打印一条错误消息。你可指定警告类别,它们是Warning的子类

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值