python異常處理(續(xù))
之前在學(xué)習(xí)python的時(shí)候有整理過python異常處理的文章,不夠簡單也不夠完整,所以決定再整理一篇,算做補(bǔ)充。
http://www.cnblogs.com/fnng/archive/2013/04/28/3048356.html
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'
打開一個(gè)不存在的文件abc.txt 文件,當(dāng)系統(tǒng)找不到abc.txt 文件時(shí),就會拋出給我們一個(gè)IOError類型的錯(cuò)誤,No such file or directory:abc.txt (沒有abc.txt這樣的文件或目錄)
Try...except...
假如,我們已經(jīng)知道這種類型的錯(cuò)誤,那么就可以通過一個(gè)異常撲捉來撲捉這個(gè)錯(cuò)誤。我們可以通過try...except 來接收這個(gè)錯(cuò)誤。打開文件寫入:
try: open("abc.txt",'r') except IOError: pass
再來運(yùn)行程序就會看不到任何錯(cuò)誤,因?yàn)槲覀冇?span style="font-family: 'Times New Roman';">except 接收了這個(gè)IOError錯(cuò)誤。pass 表示實(shí)現(xiàn)了相應(yīng)的實(shí)現(xiàn),但什么也不做。
假如我不是打開一個(gè)文件,而是輸出一個(gè)沒有定義的變量呢?
try: print aa except IOError: pass
顯然,在上面的代碼中我并沒有對aa 賦值,運(yùn)行結(jié)果:
Traceback (most recent call last): File "/home/fnngj/py_se/tryy.py", line 3, in <module> print aa NameError: name 'aa' is not defined
我們已經(jīng)用except 接收錯(cuò)誤了,為什么錯(cuò)誤還是還是拋出來了。如果你細(xì)心會發(fā)現(xiàn)這一次的錯(cuò)誤類型是NameError ,而我接收類型是IOError ,所以要想接收這個(gè)print的錯(cuò)誤,那么需要修改接收錯(cuò)誤的類型為NameError
雖然,我知道print 語句是可能會拋一個(gè)NameError 類型的錯(cuò)誤,雖然接收了這個(gè)類型錯(cuò)誤,但我不知道具體的錯(cuò)誤提示信息是什么。那么,我能不能把錯(cuò)誤信息打印出來呢?當(dāng)然可以:
try: print aa except NameError, msg: print msg
我們在接收錯(cuò)誤類型的后面定義一個(gè)變量msg用于接收具體錯(cuò)誤信息, 然后將msg接收的錯(cuò)誤信息打印。再來運(yùn)行程序:
name 'aa' is not defined
現(xiàn)在只打印了一行具體錯(cuò)誤信息。
異常的拋出機(jī)制:
1、如果在運(yùn)行時(shí)發(fā)生異常,解釋器會查找相應(yīng)的處理語句(稱為handler).
2、要是在當(dāng)前函數(shù)里沒有找到的話,它會將異常傳遞給上層的調(diào)用函數(shù),看看那里能不能處理。
3、如果在最外層(全局“main”)還是沒有找到的話,解釋器就會退出,同時(shí)打印出traceback以便讓用戶找到錯(cuò)誤產(chǎn)生的原因。
注意:雖然大多數(shù)錯(cuò)誤會導(dǎo)致異常,但一個(gè)異常不一定代表錯(cuò)誤,有時(shí)候它們只是一個(gè)警告,有時(shí)候它們可能是一個(gè)終止信號,比如退出循環(huán)等。
try...finally...
try...finally...子句用來表達(dá)這樣的情況:
我們不管線捕捉到的是什么錯(cuò)誤,無論錯(cuò)誤是不是發(fā)生,這些代碼“必須”運(yùn)行,比如文件關(guān)閉,釋放鎖,把數(shù)據(jù)庫連接返還給連接池等。
創(chuàng)建文件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'
運(yùn)行程序(在windows命令提示符或linux終端下運(yùn)行):
...$ 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文件中每一行數(shù)據(jù)打印,但是我有意在每打印一行之前用time.sleep方法暫停2秒鐘。這樣做的原因是讓程序運(yùn)行得慢一些。在程序運(yùn)行的時(shí)候,按Ctrl-c中斷/取消程序。
我們可以觀察到KeyboardInterrupt異常被觸發(fā),程序退出。但是在程序退出之前,finally從句仍然被執(zhí)行,把文件關(guān)閉。
到目前為止,我們只討論了如何捕捉異常,那么如何拋出異常呢?
Raise拋出異常
使用raise來拋出一個(gè)異常:
tryr.py
#coding=utf-8 filename = raw_input('please input file name:') if filename=='hello': raise NameError('input file name error !')
程序要求用戶輸入一個(gè)文件名,如果用戶輸入的文件名是hello ,那么拋出一個(gè)NameError的異常,用戶輸入hello 和NameError異常之間沒有任何必然聯(lián)系,我只是人為的通過raise來這樣定義,我當(dāng)然也可以定義稱TypeError ,但我定義的異常類型必須是python提供的。
附錄:
常見的python異常類型
posted on 2014-02-28 14:48 順其自然EVO 閱讀(218) 評論(0) 編輯 收藏 所屬分類: python