一、异常

异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。 一般情况下,在Python无法正常处理程序时就会发生一个异常。 异常是Python对象,表示一个错误。 当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。

捕捉异常可以使用try/except语句。 try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。 如果你不想在异常发生时结束你的程序,只需在try里捕获它。 语法: 以下为简单的try....except...else的语法: 

try: <语句>        #运行别的代码 

except <名字>: <语句>        #如果在try部份引发了'name'异常 

except <名字>,<数据>: <语句>        #如果引发了'name'异常,获得附加的数据 

else: <语句>        #如果没有异常发生

try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。 

(1)如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。 

(2)如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。 

(3)如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。

1.捕获所有异常:

try:     

   正常的操作    ...................... 

except:        //没有写明具体异常,就捕获所有异常

   发生异常,执行这块代码    ......................   

else:    

    如果没有异常执行这块代码

2.捕获所有异常

try:     

   正常的操作   

   ...................... 

except(Exception1[, Exception2[,...ExceptionN]]]):    

          发生以上多个异常中的一个,执行这块代码    

           ...................... 

else:     如果没有异常执行这块代码

3.带有finally子句的异常

try:         

    print(a / b)     

except ZeroDivisionError:         

        print("Error: b should not be 0 !!")     

except Exception as e:         

       print("Unexpected Error: {}".format(e))     else:         

       print('Run into else only when everything goes well')     

finally:         

      print('Always run into finally block.')

4.raise异常

自主抛出异常一个异常,可以使用raise关键字,等同于C#和Java中的throw语句,其语法规则如下。 

 raise NameError("bad name!") raise关键字后面需要指定你抛出的异常类型,一般来说抛出的异常越详细越好,Python在exceptions模块内建了很多的异常类型,通过使用dir()函数来查看exceptions中的异常类型

也可以自己声明一个新的异常:

只需要要从Exception类继承(直接或间接)即可: 

 class SomeCustomException(Exception):     

            pass

异常抛出在try..except....else....finally子句都可以使用

5.总结:

(1)except语句不是必须的,finally语句也不是必须的,但是二者必须要有一个,否则就没有try的意义了。 

(2)except语句可以有多个,Python会按except语句的顺序依次匹配你指定的异常,如果异常已经处理就不会再进入后面的except语句。 

(3)except语句可以以元组形式同时指定多个异常。 

(4)except语句后面如果不指定异常类型,则默认捕获所有异常,你可以通过logging或者sys模块获取当前异常。 

(5)如果要捕获异常后要重复抛出,请使用raise,后面不要带任何参数或信息。 

(6)不建议捕获并抛出同一个异常,请考虑重构你的代码。 

(7)不建议在不清楚逻辑的情况下捕获所有异常,有可能你隐藏了很严重的问题。 

(8)尽量使用内置的异常处理语句来 替换try/except语句,比如with语句,getattr()。