首先我们打开一个不存在的文件:
fp = open("null.txt","r")
然后提示报错如下:
--------------------------------------------------------------------------- IOError Traceback (most recent call last) <ipython-input-3-f70973547c7e> in <module>() ----> 1 fp = open("null.txt","r") IOError: [Errno 2] No such file or directory: 'null.txt'
接着我们使用try...except...来执行这条语句
In [4]: try: ...: fp = open("null.txt","r") ...: except: ...: print "open error" ...: open error
接着我们再在后面加一条finally语句,所谓的filally就是最后要执行的,它不管你前边是否发送错误
In [4]: try: ...: fp =open('null.txt','r') ...: except: ...: print 'opoen error' ...: finally: ...: print 'end' ...: opoen error end
接着我们使用except打印出错误类型,然后观察错误的type
In [5]: try: ...: fp = open('null.txt','r') ...: except Exception,e: ...: print e ...: print type(e) ...: [Errno 2] No such file or directory: 'null.txt' <type 'exceptions.IOError'>
我们可以看到except把错误捕捉到赋值给e,然后将其打印出,可以看到为IOError,所以在这里我们可以修改上边为:
In [9]: try: ...: fp = open('null.txt', 'r') ...: except IOError,e: ...: print "ioerror" ...: ioerror
当然这里如果不是IOError的话,上边except语句是捕捉不到的,例如:
In [10]: try: ....: a = 10/0 ....: except IOError,e: ....: print "ioerror" ....: --------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-10-e17eff88239d> in <module>() 1 try: ----> 2 a = 10/0 3 except IOError,e: 4 print "ioerror" 5 ZeroDivisionError: integer division or modulo by zero
这时我们需要另外的错误类型进行捕获,例如:
In [11]: try: ....: a = 10/0 ....: except IOError,e: ....: print "IOError" ....: except ZeroDivisionError,e: ....: print "Zero Error" ....: Zero Error可以看到第一个except并没有捕捉到错误,所以传给下一个except,当然如果所有的except都没有捕获到的话,程序就会抛出异常
在这里我们不得不注意的是,python的错误类型其实都是class,所有的错误类型都继承自BaseException
,所以在使用except
时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”。比如:
In [14]: try: ....: a = 10 /0 ....: except StandardError,e: ....: print 'standardError' ....: except ZeroDivisionError,e: ....: print 'zero error' ....: standardError
第二个
except
永远也捕获不到
ValueError
,因为
ZeroDivisionError是
StandardError
的子类,如果有,也被第一个
except
给捕获了。
使用try...except...finally的另外一个好处是,可以跨越多层调用,例如:
In [15]: def foo(m): ....: return 10/int(m) ....: In [16]: def goo(): ....: a = "0" ....: foo(a) ....: In [17]: def main(): ....: goo() ....: In [18]: try: ....: main() ....: except Exception,e: ....: print e ....: integer division or modulo by zero
在foo()函数中抛出的错误,然而在goo和main函数中都没有进行捕捉,在执行main函数时进行捕获,也可以捕获到
除了try...except...finally之外还有python的logging模块,也可以进行错误调试,当然我们也可以使用raise抛出异常