Python异常处理


异常处理的能力是一门语言好坏的重要特征。python也提供了强大的异常处理功能,如下面介绍。
1. try...except :
[python]  view plain copy
  1. try:  
  2.     #raise NameError  
  3.     pass  
  4. except NameError:  
  5.     # code to be executed when NameError occurred  
  6.     pass  
  7. except ValueError:  
  8.     # code to be executed when NameError occurred  
  9.     pass  

上述代码的执行规则如下:
首先,执行try语句中的语句。
如果在执行的过程中出现异常,则立即停止try语句的执行,执行异常处理或者停止执行(异常没有处理)
发生异常后,将异常类型按顺序与except语句中的异常匹配,如果匹配成功,执行对应的异常处理。如果匹配不成功。将异常传递给更高一级的try语句,如果异常一直未找到处理程序则停止执行,抛出异常信息。
执行流程图如下:
                                     


有几点需要注意:
  • 出现异常时一旦类型匹配成功,就执行该类型对应的异常处理。此后不再继续匹配,也就是说最多(不匹配时不执行)只有一个异常处理代码块被执行。
  • 一个except语句可以处理多种类型(组成元组)的异常,格式如下: except (RuntimError, TypeError, NameError):
  • except中可以引用异常的实例, except NameError as inst : 或者 except NameError, inst .如果出现NameError异常,err就是这个异常的实例。可以操作这个实例的方法或者属性获得更多的异常信息。
例如:
[python]  view plain copy
  1. try:  
  2.     raise Exception('spam''eggs')  
  3. except Exception as inst :  
  4.     print(type(inst))   #<class 'Exception'>  
  5.     print(inst.args)    #(argument tuple)  
  6.     print(inst)            

这段代码中,抛出异常时我们传递了两个参数 spam和eggs,这两个参数被组成一个元组,存储在异常实例的args属性中,因此print inst.args将输出(‘spam’, 'eggs').由于这个异常实例定义了__str__方法,所以可以直接将它输出,输出结果与print inst.args一样。如果一个传递了参数的异常没有被处理,那么在抛出的异常信息最后一部分会是所传递的参数。假设上面抛出的异常没有处理(即去掉except语句),则输出的异常信息最后一部分是: Exception: ('spam', 'eggs')

2. try ... except ... else:
else语句是可选的,它在没有出现异常的时候被执行。也就是说,try语句没有异常时,执行else语句。try语句出现异常时,按照1中的规则执行,忽略else语句。

3. try...finally
[python]  view plain copy
  1. try:  
  2.     #You do your operations here;  
  3.     pass  
  4.     #Due to any exception, this may be skipped.  
  5. finally:  
  6.     pass  
  7.     #This would always be executed.  


在这种情形中,finally语句总会被执行,无论try是否出现异常。
下面是一个很好的例子:

[python]  view plain copy
  1. try:  
  2.     fh = open("testfile""w")  
  3.     try:    
  4.         fh.write("This is my test file for exception handling!!")  
  5.     finally:  
  6.         fh.close()  
  7. except IOError:  
  8.     print("Error: can\'t find file or read data")  
  9. else :  
  10.     print("Everything goes well")  



上述代码中,在执行内部try语句时,写完文件之后,finally一定会被执行,也就是文件一定会关闭。这段代码中有两处可能出现异常,open和write。如果在open出现异常,内部try不被执行,直接进行异常处理输出“Error: can\'t find file or read data”。如果open不出现异常,继续执行内部try,无论内部try是否出现异常close总会被执行。内部try出现异常,由于内部try没有except语句,所以异常被传递给外部try语句,匹配IOError成功,执行异常处理,输出“Error: can\'t find file or read data”。不出现异常的时候,执行else语句。
另一个例子:
[python]  view plain copy
  1. def divide(x, y):  
  2.     try:  
  3.         result = x / y  
  4.     except ZeroDivisionError:  
  5.         print("division by zero!")  
  6.     else:  
  7.         print("result is", result)  
  8.     finally:  
  9.         print("executing finally clause")  


执行divide(2, '2')时,结果如下:
executing finally clause
Traceback (most recent call last):
  File "D:\eclipse\workspace\python\exception\try_exception.py", line 11, in <module>
    divide(2,'2')
  File "D:\eclipse\workspace\python\exception\try_exception.py", line 3, in divide
    result = x / y
TypeError: unsupported operand type(s) for /: 'int' and 'str'

4. raise 抛出异常
除了程序运行时出现异常外,我们也可以人为地抛出任意类型的异常。e.g:
raise NameError("TEST")
raise后面只能跟着一个异常。这个异常可是是异常类,也可是是异常实例。
如果你只想知道是否出现异常,不想去处理异常,有一种方法可以重新抛出异常:
[python]  view plain copy
  1. try:  
  2.     raise NameError("Hello")  
  3. except NameError:  
  4.     print "a NameEerror occurs"  
  5.     raise  


这段代码执行结果如下:
a NameEerror occurs

Traceback (most recent call last):
  File "<pyshell#1>", line 2, in <module>
    raise NameError("Hello")
NameError: Hello


5. 自定义异常
python允许程序员通过继承内置的异常类型来定制自己的异常类型。
[python]  view plain copy
  1. class MyError(Exception):  
  2.     def __init__(self, value):  
  3.         self.value = value  
  4.     def __str__(self):  
  5.         return repr(self.value)  
  6. try:  
  7.     raise MyError(4)  
  8. except MyError as inst:  
  9.     print("opps, MyError occurred, value:", inst.value)  


这段代码执行结果为:opps, MyError occurred, value: 4
自定义异常类型的时候,尽量保持简单,提供有效的异常信息即可。

以上几点只是简单介绍,详细内容请参考官方文档。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值