異常是一個事件,改事件會在程序執行過程當中發生,影響程序的正常執行,通常狀況下,在python中沒法處理程序時就會發生異常,異常時Python的一個對象,表示一個錯誤,當Python腳本發生異常時,咱們須要捕獲並處理異常,不然程序就會終止執行。python
當Python腳本出現異常的時候咱們怎麼處理那?
就如咱們使用的工具出現了一點毛病,咱們能夠想辦法修理好它,程序也是同樣,以前的前輩們通過不斷的積累與思考,創造了不少好得方法處理程序中出現的異常,本章咱們就講一下使用try語句處理異常。
首先咱們來講一下try語句的語法:
try語句與except 相結合使用,此語句用來檢測try語句塊中的錯誤,從而讓except語句捕獲異常信息並處理,若是不想在發生異常時結束程序,只須要在try語句中捕獲異常便可express
try: <代碼塊>
except <異常名字>
print(‘語句’) 實例以下: def func(): try: a = x/y print('a=',a) return a eccept Exception: print('程序出現異常,異常信息:被除數爲0')
在Python中使用raise語句拋出一個指定的異常,咱們可使用類或實例參數調用raise語句引起異常。
實例以下:app
class EvaException(BaseException): def __init__(self,msg): self.msg=msg def __str__(self): return self.msg try: raise EvaException('類型錯誤') except EvaException as e: print(e)
咱們前面說了怎麼處理一個異常的狀況,若是涉及到多個,咱們該怎麼處理那?
在Python中支持一個try/except語句處理多個異常,語法以下:
ide
try: <語句> except <異常名字>: print(‘異常說明’) except <異常名字>: print(‘異常說明’) try語句的工做方式以下:
首次執行try中語句塊,若是沒有發生異常,則忽略except中的字句,try語句中的代碼塊執行後結束。若是try語句中的代碼塊出現異常,try中的剩餘語句則會被忽略,
若是異常和eccept中的異常名字一直,相應的except語句就會被執行。若是一個異常也沒有匹配,這個異常就會傳遞給上層的try語句中,一個語句可能包含第一個except語句,
分別處理不一樣的異常,可是最多隻有一個分支會執行。
try:
#a
#1/0
dic = {1:2}
dic[3]
except NameError:
print('名字沒有定義,報錯了')
except ZeroDivisionError:
print('0不能當作除數,報錯了')
except KeyError:
print('沒有這個key')
咱們若是程序執行完異常後還想作其餘的事情怎麼辦?
這時咱們就能夠用到異常中的else了,具體語法以下:
工具
try: <語句>
except <異常名字> : <語句>
except <異常名字>: <語句>
else: <語句> #(try語句中沒有異常後執行此段代碼)
若是在try語句中執行沒有發生異常,就會執行else語句,使用else語句比把全部語句都放在try字句裏面更好,這樣能夠避免一些意想不到的而except有沒有捕獲到的異常: def func(x,y): try: a = x/y except : print('Error,happened') else: print('It went as execpt') func(2,1)
你能夠經過建立一個新的exception類來擁有本身的異常。異常應該繼承自 Exception 類,或者直接繼承,或者間接繼承,例如:oop
class MyError(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) try: raise MyError(2*2) except MyError as e: print('My exception occurred, value:', e.value) My exception occurred, value: 4
raise MyError('oops!') Traceback (most recent call last): File "<stdin>", line 1, in ? main__.MyError: 'oops!' 在這個例子中,類 Exception 默認的 __init__() 被覆蓋。 當建立一個模塊有可能拋出多種不一樣的異常時,一種一般的作法是爲這個包創建一個基礎異常類,而後基於這個基礎類爲不一樣的錯誤狀況建立不一樣的子類: class Error(Exception): """Base class for exceptions in this module."""
pass
class InputError(Error): """Exception raised for errors in the input. Attributes: expression -- input expression in which the error occurred message -- explanation of the error """
def __init__(self, expression, message): self.expression = expression self.message = message class TransitionError(Error): """Raised when an operation attempts a state transition that's not allowed. Attributes: previous -- state at beginning of transition next -- attempted new state message -- explanation of why the specific transition is not allowed """
def __init__(self, previous, next, message): self.previous = previous self.next = next self.message = message 大多數的異常的名字都以"Error"結尾,就跟標準的異常命名同樣。
try 語句還有另一個可選的子句,它定義了不管在任何狀況下都會執行的清理行爲。 例如:this
>>> try: ... raise KeyboardInterrupt ... finally: ... print('Goodbye, world!') ... Goodbye, world! Traceback (most recent call last): File "<stdin>", line 2, in <module> KeyboardInterrupt 以上例子無論 try 子句裏面有沒有發生異常,finally 子句都會執行。 若是一個異常在 try 子句裏(或者在 except 和 else 子句裏)被拋出,而又沒有任何的 except 把它截住,那麼這個異常會在 finally 子句執行後再次被拋出。 下面是一個更加複雜的例子(在同一個 try 語句裏包含 except 和 finally 子句): >>> def divide(x, y): try: result = x / y except ZeroDivisionError: print("division by zero!") else: print("result is", result) finally: print("executing finally clause") >>> divide(2, 1) result is 2.0 executing finally clause >>> divide(2, 0) division by zero! executing finally clause >>> divide("2", "1") executing finally clause Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 3, in divide TypeError: unsupported operand type(s) for /: 'str' and 'str' 預約義的清理行爲 一些對象定義了標準的清理行爲,不管系統是否成功的使用了它,一旦不須要它了,那麼這個標準的清理行爲就會執行。 這面這個例子展現了嘗試打開一個文件,而後把內容打印到屏幕上: for line in open("myfile.txt"): print(line, end="") 以上這段代碼的問題是,當執行完畢後,文件會保持打開狀態,並無被關閉。 關鍵詞 with 語句就能夠保證諸如文件之類的對象在使用完以後必定會正確的執行他的清理方法: with open("myfile.txt") as f: for line in f: print(line, end="") 以上這段代碼執行完畢後,就算在處理過程當中出問題了,文件 f 老是會關閉。
異常名稱 | 描述 |
---|---|
BaseException | 全部異常的基類 |
SystemExit | 解釋器請求退出 |
KeyboardInterrupt | 用戶中斷執行(一般是輸入^C) |
Exception | 常規錯誤的基類 |
StopIteration編碼 |
迭代器沒有更多的值 |
GeneratorExit | 生成器(generator)發生異常來通知退出 |
StandardError | 全部的內建標準異常的基類 |
ArithmeticError | 全部數值計算錯誤的基類 |
FloatingPointError | 浮點計算錯誤 |
OverflowError | 數值運算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (全部數據類型) |
AssertionError | 斷言語句失敗 |
AttributeError | 對象沒有這個屬性 |
EOFError | 沒有內建輸入,到達EOF 標記 |
EnvironmentError | 操做系統錯誤的基類 |
IOError | 輸入/輸出操做失敗 |
OSError | 操做系統錯誤 |
WindowsError | 系統調用失敗 |
ImportError | 導入模塊/對象失敗 |
LookupError | 無效數據查詢的基類 |
IndexError | 序列中沒有此索引(index) |
KeyError | 映射中沒有這個鍵 |
MemoryError | 內存溢出錯誤(對於Python 解釋器不是致命的) |
NameError | 未聲明/初始化對象 (沒有屬性) |
UnboundLocalError | 訪問未初始化的本地變量 |
ReferenceError | 弱引用(Weak reference)試圖訪問已經垃圾回收了的對象 |
RuntimeError | 通常的運行時錯誤 |
NotImplementedError | 還沒有實現的方法 |
SyntaxError | Python 語法錯誤 |
IndentationError | 縮進錯誤 |
TabError | Tab 和空格混用 |
SystemError | 通常的解釋器系統錯誤 |
TypeError | 對類型無效的操做 |
ValueError | 傳入無效的參數 |
UnicodeError | Unicode 相關的錯誤 |
UnicodeDecodeError | Unicode 解碼時的錯誤 |
UnicodeEncodeError | Unicode 編碼時錯誤 |
UnicodeTranslateError | Unicode 轉換時錯誤 |
Warning | 警告的基類 |
DeprecationWarning | 關於被棄用的特徵的警告 |
FutureWarning | 關於構造未來語義會有改變的警告 |
OverflowWarning | 舊的關於自動提高爲長整型(long)的警告 |
PendingDeprecationWarning | 關於特性將會被廢棄的警告 |
RuntimeWarning | 可疑的運行時行爲(runtime behavior)的警告 |
SyntaxWarning | 可疑的語法的警告 |
UserWarning | 用戶代碼生成的警告 |