标签:
Python使用try语句实现异常处理。try语句包围着可能引发异常的其他语句。try语句以关键字try开头,后续一个冒号(:)和一个可能在其中引发异常的代码。try语句可指定一个或多个except子句,它们紧接在try suite之后。每个except子句都指定了零个或多个异常类名,它们代表要由except子句处理的异常类型。可在except子句中指定一个标志符,程序用它引用被捕捉的异常对象。处理程序利用标识符从异常对象获取也异常有关的信息。如果except子句中没有指定异常类型,就称为"空白except子句"。这种子句会捕捉所有异常类型。在最后一个except子句之后,可选择性地添加一个else子句。如果try suite中的代码没有引发异常,就会执行else子句中的代码。如果try语句没有指定except子句,那就必须包含一个finally子句----该子句肯定会执行,无论是否发生异常。
在try语句中同时包括except和finally子句是语法错误,可接受的组合形式只有:
1 try: ...... #可能得到异常的语句 except #锁定是哪种异常except
Exception,e:
#捕获所有异常 ...... #出现异常的处理方法 2 try: ...... except ....... else ...... 3 try: ...... finally ........
一旦程序代码导致异常,或Python解释器检测到问题,代码或解释器就会“引发”一个异常。有的程序员将程序中发生异常的位置称为“引发点”。异常是一些类的对象,这些类都是从Exception类继承的。如果在一个try suite中发生异常,这个try suite会立即“超时”(即立即终止),程序控制权会移交给try suite之后的第一个except处理程序(如果有的话),接着解释器搜索可对这种异常类型进行处理的第一个except处理程序。解释器为了确定相匹配的except,需要将引发的异常的类型与每个except处理程序的异常类型比较,直到最终发现相匹配的为止。如类型完全一致,或引发的异常的类型是except处理程序的异常类型的一个派生类,就表明发生了匹配。如果try suite中没有发生异常,解释器将忽略用于try语句的异常处理程序,并执行try语句的else子句(如果有的话)。如果没有发生异常,或者某个except子句成功处理了异常,程序会从try语句之后的下一个语句恢复执行。如果在某个语句中发生了一个异常,但该语句不在一个try suite 中,而是一在一个函数中,那么包含那个语句的函数会立即终止,解释器会试图在(发出)调用(的)代码中查找一个封闭的try语句,这个过程称为“堆栈辗转开解”(Stacking Unwinding)。
----------------------------------------------------------------------------------------------
python shell
>>> open(‘abc.txt‘,‘r‘) Traceback (most recent call last): File "<stdin>", line 1, in <module> IOError: [Errno 2] No such file or directory: ‘abc.txt‘
打开一个不存在的文件abc.txt 文件,当系统找不到abc.txt 文件时,就会抛出给我们一个IOError类型的错误,No such file or directory:abc.txt (没有abc.txt这样的文件或目录)
Try...except...
假如,我们已经知道这种类型的错误,那么就可以通过一个异常扑捉来扑捉这个错误。我们可以通过try...except 来接收这个错误。打开文件写入:
try: open("abc.txt",‘r‘) except IOError: pass
再来运行程序就会看不到任何错误,因为我们用except 接收了这个IOError错误。pass 表示实现了相应的实现,但什么也不做。
假如我不是打开一个文件,而是输出一个没有定义的变量呢?
try: print aa except IOError: pass
显然,在上面的代码中我并没有对aa 赋值,运行结果:
Traceback (most recent call last): File "/home/fnngj/py_se/tryy.py", line 3, in <module> print aa NameError: name ‘aa‘ is not defined
我们已经用except 接收错误了,为什么错误还是还是抛出来了。如果你细心会发现这一次的错误类型是NameError ,而我接收类型是IOError ,所以要想接收这个print的错误,那么需要修改接收错误的类型为NameError
虽然,我知道print 语句是可能会抛一个NameError 类型的错误,虽然接收了这个类型错误,但我不知道具体的错误提示信息是什么。那么,我能不能把错误信息打印出来呢?当然可以:
try: print aa except NameError, msg: print msg
我们在接收错误类型的后面定义一个变量msg用于接收具体错误信息, 然后将msg接收的错误信息打印。再来运行程序:
name ‘aa‘ is not defined
现在只打印了一行具体错误信息。
异常的抛出机制:
1、如果在运行时发生异常,解释器会查找相应的处理语句(称为handler).
2、要是在当前函数里没有找到的话,它会将异常传递给上层的调用函数,看看那里能不能处理。
3、如果在最外层(全局“main”)还是没有找到的话,解释器就会退出,同时打印出traceback以便让用户找到错误产生的原因。
注意:虽然大多数错误会导致异常,但一个异常不一定代表错误,有时候它们只是一个警告,有时候它们可能是一个终止信号,比如退出循环等。
try...finally...
try...finally...子句用来表达这样的情况:
我们不管线捕捉到的是什么错误,无论错误是不是发生,这些代码“必须”运行,比如文件关闭,释放锁,把数据库连接返还给连接池等。
创建文件poem.txt
tryf.py
import time try: f = file(‘poem.txt‘) while True: # our usual file-reading idiom line = f.readline() if len(line) == 0: break time.sleep(2) print line,
finally: f.close() print ‘Cleaning up...closed the file‘
运行程序(在windows命令提示符或linux终端下运行):
...$ python tryf.py abc efg ^CCleaning up...closed the file Traceback (most recent call last): File "tryy.py", line 18, in <module> time.sleep(2) KeyboardInterrupt
程序读poem.txt文件中每一行数据打印,但是我有意在每打印一行之前用time.sleep方法暂停2秒钟。这样做的原因是让程序运行得慢一些。在程序运行的时候,按Ctrl-c中断/取消程序。
我们可以观察到KeyboardInterrupt异常被触发,程序退出。但是在程序退出之前,finally从句仍然被执行,把文件关闭。
到目前为止,我们只讨论了如何捕捉异常,那么如何抛出异常呢?
Raise抛出异常
使用raise来抛出一个异常: 主动抛出一个异常,想让程序停止,可以主动抛出一个异常,与exit相比:有明确的原因
tryr.py
#coding=utf-8
filename = raw_input(‘please input file name:‘)
if filename==‘hello‘:
raise NameError(‘input file name error !‘)
程序要求用户输入一个文件名,如果用户输入的文件名是hello ,那么抛出一个NameError的异常,用户输入hello 和NameError异常之间没有任何必然联系,我只是人为的通过raise来这样定义,我当然也可以定义称TypeError ,但我定义的异常类型必须是python提供的。
附录:
常见的python异常类型
标签:
原文地址:http://www.cnblogs.com/wjoyxt/p/5104866.html