文章目錄
- Python內建異常體繫結構
- raise
- 異常的慣用法
- 異常捕獲模式
Python內建異常體繫結構
BaseException+-- SystemExit+-- KeyboardInterrupt+-- GeneratorExit+-- Exception+-- StopIteration+-- StandardError| +-- BufferError| +-- ArithmeticError| | +-- FloatingPointError| | +-- OverflowError| | +-- ZeroDivisionError| +-- AssertionError| +-- AttributeError| +-- EnvironmentError| | +-- IOError| | +-- OSError| | +-- WindowsError (Windows)| | +-- VMSError (VMS)| +-- EOFError| +-- ImportError| +-- LookupError| | +-- IndexError| | +-- KeyError| +-- MemoryError| +-- NameError| | +-- UnboundLocalError| +-- ReferenceError| +-- RuntimeError| | +-- NotImplementedError| +-- SyntaxError| | +-- IndentationError| | +-- TabError| +-- SystemError| +-- TypeError| +-- ValueError| +-- UnicodeError| +-- UnicodeDecodeError| +-- UnicodeEncodeError| +-- UnicodeTranslateError+-- Warning+-- DeprecationWarning+-- PendingDeprecationWarning+-- RuntimeWarning+-- SyntaxWarning+-- UserWarning+-- FutureWarning+-- ImportWarning+-- UnicodeWarning+-- BytesWarning
-
try
-
捕獲由Python或程式本身引發的異常
-
raise
-
手工地引發一個異常
為什麼要使用異常
- 錯誤處理,當python檢查以程式運行時的錯誤就引發異常,你可以在程式裡捕捉和處理這些錯誤,或者忽略它們。
- 事件通知,異常也可以作為某種條件的訊號,而不需要在程式裡傳送結果標誌或顯式地測試它們。
- 特殊情形處理,有時有些情況是很少發生的,把相應的處理代碼改為異常處理會更好一些。
- 奇特的控制流程,異常是一個高層次的"goto",可以把它作為實現奇特的控制流程的基礎。如反向跟蹤等。
異常的基礎知識
python的try語句有兩種風格---一種是處理異常(try/except/else),一種是無論是否發生異常都將執行最後的代碼(try/finally)。
try/except/else風格
try: <語句> #運行別的代碼 except <名字>: <語句> #如果在try部份引發了'name'異常 except <名字>,<資料>: <語句> #如果引發了'name'異常,獲得附加的資料 else: <語句> #如果沒有異常發生
try的工作原理是,當開始一個try語句後,python就在當前程式的上下文中作標記,這樣當異常出現時就可以回到這裡,try子句先執行,接下來會發生什麼依賴於執行時是否出現異常。
- 如果當try後的語句執行時發生異常,python就跳回到try並執行第一個匹配該異常的except子句,異常處理完畢,控制流程就通過整個try語句(除非在處理異常時又引發新的異常)。
- 如果在try後的語句裡發生了異常,卻沒有匹配的except子句,異常將被遞交到上層的try,或者到程式的最上層(這樣將結束程式,並列印預設的出錯資訊)。
- 如果在try子句執行時沒有發生異常,python將執行else語句後的語句(如果有else的話),然後控制流程通過整個try語句。
try/finally風格
try: <語句> finally: <語句> #退出try時總會執行 raise
python總會執行finally子句,無論try子句執行時是否發一異常。
- 如果沒有發生異常,python運行try子句,然後是finally子句,然後繼續。
- 如果在try子句發生了異常,python就會回來執行finally子句,然後把異常遞交給上層try,控制流程不會通過整個try語句。
當你想無論是否發生異常都確保執行某些代碼時,try/finally是有用的。
raise
要引發異常,你需要寫raise語句,它的形式很簡單,raise後面跟著要引發的異常。
raise <name> #手工地引發異常 raise <name>,<data> #傳遞一個附加的資料
什麼是異常名(name)呢?它也許是內建範圍內的內建異常(如IndexError),或者是你程式中的任一字元串對象。
預設行為:顯示錯誤資訊。
$ python test.py Traceback (innermost last): File "test.py", line 3, in ? a = 1 /0 ZeroDivisionError: integer division or modulo
當一個未捕獲的異常發生時,python將結束程式並列印一個堆疊追蹤資訊,以及異常名和附加資訊。
用try捕獲內建異常
如果你不想在異常發生時結束你的程式,只需在try裡捕獲它。
#!/usr/bin/python try: a = 1 /0 print a except: print 'i get the error'
當程式運行是會捕獲一個錯誤並執行except後面的代碼。
異常的慣用法
異常並不總是壞事情,例如,檔案對象的read方法在檔案尾時返回一個空串,python也提供一個內建函數raw_input,它從標準輸入資料流讀入。與read方法不同,當遇到檔案尾時,raw_input()引發內建的EOFError錯誤。所以可以這樣用:
while 1: try: line = raw_input() #從stdin讀入行 except EOFError: break #在檔案末尾退出迴圈 esle: # 其它處理代碼
用異常傳遞成功的訊號
Found = 'item found' def search(): 引發或返回Found try: search() except Found: successful else: fail
可以使用try來調試代碼,你可以用自已的異常處理替換python預設的異常處理。把整個程式封裝在一個外部try裡面,你可以捕獲運行時的任何異常。
異常捕獲模式
try語句子句形式表 except: 捕獲所有異常 except name: 只捕獲特定的異常 except name,value: 捕獲異常和它的附加資料 except (name1,name2): 捕獲任何列出的異常 else: 如果沒有異常 finally: 總是執行
捕獲多個異常中的一個,python從上到下地查看except子句,括弧裡列出多個異常與列出單獨的異常是一樣的,只是更簡潔一些。
運行時嵌套的異常,python會匹配最近的except。
finally子句無論如何都會執行,所以它是做清除動作的好地方,如關閉一個檔案的操作。
捕捉所有異常
try: # 你的代碼except BaseException, e: print(str(e))