當你的程序中出現某些 異常的 狀況的時候,異常就發生了。例如,當你想要讀某個文件的時候,而那個文件不存在。或者在程序運行的時候,你不小心把它刪除了。
那麼如果你是在IDE中運行,一個錯誤發生,異常會被打引出來,這便是未處理異常;當異常發生時,如果沒有代碼去關注和處理它,這些異常會傳給置在Python中的缺省處理,他會輸出一些調試信息並且終止運行。如果是在IDE中,這不是什麼大事,但是如果是Python程序運行中的異常,它會導致整個程序終止,對於這些情況可以使用異常來處理。
1.try..except
我們可以使用try..except語句來處理異常。我們把通常的語句放在try-塊中,而把我們的錯誤處理語句放在except-塊中。
注:在try...except塊可以有一個else子句,就像if語句,如果在try中沒有異常引發,然後else子句就執行!!!
eg.
#!/usr/bin/python # -*- coding: utf-8 -*- import sys try: # 把所有可能引發錯誤的語句放在try塊中,然後在except從句/塊中處理所有的錯誤和異常。 s = raw_input('Enter something --> ') except EOFError: # except從句可以專門處理單一的錯誤或異常,或者一組包括在圓括號內的錯誤/異常。EOFError的錯誤,這個錯誤基本上意味着它發現一個不期望的 文件尾(由Ctrl-d表示) print '\nWhy did you do an EOF on me?' sys.exit() # 退出程序 except: # 如果沒有給出錯誤或異常的名稱,它會處理*所有的*錯誤和異常。 print '\nSome error/exception occurred.' else: # 沒有引發錯誤就執行此句 print "Haha,you are so right!"
上面的例子中,我們只指明瞭一個EOFError錯誤(使用Ctrl+D異常退出),在最後還使用了一個不指定類型的except(用來解決全部的錯誤),所以運行結果如下:
long@zhouyl:/tmp/test$ python try_excepy.py # 輸入正常信息,會執行else語句中的,沒有異常提醒 Enter something --> 123 Haha,you are so right! long@zhouyl:/tmp$ python try_excepy.py Enter something --> # 這裏是輸入Enter,沒有異常提示 Haha,you are so right! long@zhouyl:/tmp$ python try_excepy.py Enter something --> ^C # 輸入Ctrl+C退出,提示的爲最後未加類型的except Some error/exception occurred. long@zhouyl:/tmp$ python try_excepy.py Enter something --> # 輸入Ctrl+D退出,提示爲except EOFError後面的部分 Why did you do an EOF on me?
2.引發異常
你可以使用raise語句 引發 異常。你還得指明錯誤/異常的名稱和伴隨異常 觸發的 異常對象。你可以引發的錯誤或異常應該分別是一個Error或Exception類的直接或間接導出類。
eg.
#!/usr/bin/python # -*- coding: utf-8 -*- class ShortInputException(Exception): # ShortInputException爲我們自己定義的異常類型 '''A user-defined exception class.''' # doc string ,可以使用ShortInputException.__doc__ 打 印這個信息 def __init__(self, length, atleast): # 定義初始化 Exception.__init__(self) self.length = length self.atleast = atleast try: # try 接着可能發生錯誤的語句 s = raw_input('Enter something --> ') if len(s) < 3: # 假如輸入字符串數的小於3,使用raise引發定義的ShortInputException異常。 raise ShortInputException(len(s), 3) # Other work can continue as usual here except EOFError: # 上面說到過,EOFError是不正常的文件尾(由Ctrl-d引發) print '\nWhy did you do an EOF on me?' except ShortInputException, x: # raise的異常在這處理,此處爲打印一些一場信息 print 'ShortInputException: The input was of length %d, \ was expecting at least %d' % (x.length, x.atleast) else: print 'No exception was raised.'
上面的程序已經大概介紹了怎麼運行,raise怎麼引發我們自己定義的異常,運行效果如下:
long@zhouyl:/tmp$ python raise.py Enter something --> ab # 輸入兩個字符,不滿足3個字符,raise引發我們自己定義的ShortInputException異常 ShortInputException: The input was of length 2, was expecting at least 3 long@zhouyl:/tmp$ python raise.py Enter something --> # 沒輸入字符!仍然raise異常 ShortInputException: The input was of length 0, was expecting at least 3 long@zhouyl:/tmp$ python raise.py Enter something --> # Ctrl+D引發except EOFError異常 Why did you do an EOF on me? long@zhouyl:/tmp$ python raise.py Enter something --> abcdefg # 輸入7個字符,運行正常! No exception was raised.
3.try..finally
假如你在讀一個文件的時候,希望在無論異常發生與否的情況下都關閉文件,該怎麼做呢?這可以使用finally塊來完成。
注:在一個try塊下,你可以同時使用except從句和finally塊。如果你要同時使用它們的話,需要把一個嵌入另外一個。
eg.
#!/usr/bin/python # -*- coding: utf-8 -*- import time # 應用time庫,下面使用到了其中的sleep函數 try: # 下面接的是可能出錯的語句,但是不管出錯不出錯,finally中的都要執行 f = file('poem.txt') # 讀模式打開 while True: # 以while循環運行其中的讀文件,一行一行讀直到break line = f.readline() # 讀一行 if len(line) == 0: # 假如讀到EOF就break break time.sleep(2) # sleep 2秒 print line, # 加了逗號,不會自動換行 finally: f.close() print 'Cleaning up...closed the file'
上面已經說過,如果try部分運行異常了仍然會運行finally部分,所以我們在讀文件時每讀一行添加了兩秒睡眠,如果我們在讀過程中中斷,效果如下:
long@zhouyl:/tmp$ python finally.py
This is the python poem
using for txt read
do you like me?
^CCleaning up...closed the file # 在此,我們使用Ctrl+D中斷運行,finnaly中的關閉文件仍然運行
Traceback (most recent call last):
File "finally.py", line 11, in <module>
time.sleep(2) # sleep 2秒
4. 一個綜合小例子
當然,我們可以將幾種異常處理綜合在一起,做出個比較強大的異常捕獲方法!
一般情況下,我們不會直接將try...execpt和try...finally一起使用,如果需要使用則需要使用嵌套!
eg.
#!/usr/bin/python # -*- coding: utf-8 -*- import os import time # 應用time庫,下面使用到了其中的sleep函數 class FileExistException(Exception): # 我們自己定義的異常類型 '''A user-defined exception class for test the file exist''' # doc string def __init__(self, name): # 定義初始化 Exception.__init__(self) self.name = name # 腳本從這開始哦~ try: # 下面接的是可能出錯的語句,但是不管出錯不出錯,finally中的都要執行 file_name = raw_input("Input the file you want to open:\t") if os.path.exists(file_name) == False: # 假如文件不存在,引發FileExistException異常。 raise FileExistException(file_name) else: print "File exist ,everything goes well" except EOFError: # EOFError是不正常的文件尾(由Ctrl-d引發) print '\nWhy did you do an EOF on me?' except FileExistException,x: # raise的異常在這處理,此處爲打印一些一場信息 print "self defined Exception is raised ,the file \"%s\" not exist " % x.name else: print "No exception was raised,Now Opening the file %s ..." % file_name try: f = file(file_name) # 讀模式打開 while True: # 以while循環運行其中的讀文件,一行一行讀直到break line = f.readline() # 讀一行 if len(line) == 0: # 假如讀到EOF就break break time.sleep(2) # sleep 2秒 print line, # 加了逗號,不會自動換行 print "\nHello ,Now I will show a jump ~~~\n" try: # 又嵌套一層,不要太迷糊,我在這主要就是想多玩玩幾層嵌套! f.seek(-128,2) # 重新跳轉到倒數128個字節上,可能引發異常! (可以根據文件大小多測試幾個數值) # 如果不引發異常,就在下一行中讀取倒數128字節的文件內容 # 如果引發異常,我們可以學習下這幾層嵌套會如何執行。我們會發現它先執行except塊再執行finally塊 f.read() except IOError: print "seek file error,may your file is not large enough" except IOError: # 前面已經通過我們自己定義的異常檢查了文件是否存在,但是在打開時以及閱讀時仍然可能引發異常 print " open file error ,maybe your file is not so good!" finally: # 爲了文件安全,如果引發異常就在此執行關閉文件操作! f.close() print 'Cleaning up...closed the file'
運行結果與分析如下:
long@zhouyl:/tmp/test$ python python_execpt.py Input the file you want to open: file # 輸入一個不存在的文件名,引發我們自定義的異常 self defined Exception is raised ,the file "file" not exist long@zhouyl:/tmp/test$ python python_execpt.py Input the file you want to open: poem.txt File exist ,everything goes well No exception was raised,Now Opening the file poem.txt ... This is the python poem using for txt read do you like me? whatever I like myself ^CCleaning up...closed the file # 在此,我們使用Ctrl+D中斷運行,finnaly中的關閉文件仍然運行 Traceback (most recent call last): File "python_execpt.py", line 31, in <module> time.sleep(2) # sleep 2秒 KeyboardInterrupt long@zhouyl:/tmp/test$ python python_execpt.py Input the file you want to open: poem.txt File exist ,everything goes well No exception was raised,Now Opening the file poem.txt ... This is the python poem using for txt read do you like me? whatever I like myself I'm selfconfidence Hello ,Now I will show a jump ~~~ seek file error,may your file is not large enough # 引發seek處的except Cleaning up...closed the file # 繼續調用finally中的關閉文件操作 long@zhouyl:/tmp/test$