之前在學習python的時候有整理過python異常處理的文章,不夠簡單也不夠完整,所以決定再整理一篇,算做補充。 http://www.cnblogs.com/cmt110/p/7464748.html python shell 打開一個不存在的文件abc.txt 文件,當系統找不到abc.txt ...
之前在學習python的時候有整理過python異常處理的文章,不夠簡單也不夠完整,所以決定再整理一篇,算做補充。
http://www.cnblogs.com/cmt110/p/7464748.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'
打開一個不存在的文件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來拋出一個異常:
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異常類型