一、什么是異常處理
定義:異常處理就是我們在寫Python時,經常看到的報錯信息,例如;NameError TypeError ValueError等,這些都是異常。
異常是一個事件,改事件會在程序執行過程中發生,影響程序的正常執行,一般情況下,在python中無法處理程序時就會發生異常,異常時Python的一個對象,表示一個錯誤,當Python腳本發生異常時,我們需要捕獲并處理異常,否則程序就會終止執行。
二、異常處理
當Python腳本出現異常的時候我們怎么處理那?
就如我們使用的工具出現了一點毛病,我們可以想辦法修理好它,程序也是一樣,之前的前輩們經過不斷的積累與思考,創造了很多好得方法處理程序中出現的異常,本章我們就講一下使用try語句處理異常。
首先我們來說一下try語句的語法:
try語句與except 相結合使用,此語句用來檢測try語句塊中的錯誤,從而讓except語句捕獲異常信息并處理,如果不想在發生異常時結束程序,只需要在try語句中捕獲異常即可
try:<代碼塊> except <異常名字>print(‘語句')實例如下:def func():try:a = x/yprint('a=',a)return aeccept Exception:print('程序出現異常,異常信息:被除數為0')三、拋出異常
在Python中使用raise語句拋出一個指定的異常,我們可以使用類或實例參數調用raise語句引發異常。
實例如下:
class EvaException(BaseException):def __init__(self,msg):self.msg=msgdef __str__(self):return self.msgtry:raise EvaException('類型錯誤')except EvaException as e:print(e)四、捕捉多個異常
我們前面說了怎么處理一個異常的情況,如果涉及到多個,我們該怎么處理那?
在Python中支持一個try/except語句處理多個異常,語法如下:
try:<語句>except <異常名字>:print(‘異常說明')except <異常名字>:print(‘異常說明')try語句的工作方式如下: 首次執行try中語句塊,如果沒有發生異常,則忽略except中的字句,try語句中的代碼塊執行后結束。如果try語句中的代碼塊出現異常,try中的剩余語句則會被忽略,如果異常和eccept中的異常名字一直,相應的except語句就會被執行。如果一個異常也沒有匹配,這個異常就會傳遞給上層的try語句中,一個語句可能包含第一個except語句,分別處理不同的異常,但是最多只有一個分支會執行。try:#a#1/0dic = {1:2}dic[3]except NameError:print('名字沒有定義,報錯了')except ZeroDivisionError:print('0不能當做除數,報錯了')except KeyError:print('沒有這個key')五、異常中else
我們如果程序執行完異常后還想做其他的事情怎么辦?
這時我們就可以用到異常中的else了,具體語法如下:
try:<語句>except <異常名字> :<語句>except <異常名字>:<語句>else:<語句> #(try語句中沒有異常后執行此段代碼)如果在try語句中執行沒有發生異常,就會執行else語句,使用else語句比把所有語句都放在try字句里面更好,這樣可以避免一些意想不到的而except有沒有捕獲到的異常:def func(x,y):try:a = x/yexcept :print('Error,happened')else:print('It went as execpt')func(2,1)六、用戶自定義異常
你可以通過創建一個新的exception類來擁有自己的異常。異常應該繼承自 Exception 類,或者直接繼承,或者間接繼承,例如:
class MyError(Exception):def __init__(self, value):self.value = valuedef __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: 4raise 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."""passclass InputError(Error):"""Exception raised for errors in the input.Attributes:expression -- input expression in which the error occurredmessage -- explanation of the error"""def __init__(self, expression, message):self.expression = expressionself.message = messageclass TransitionError(Error):"""Raised when an operation attempts a state transition that's notallowed.Attributes:previous -- state at beginning of transitionnext -- attempted new statemessage -- explanation of why the specific transition is not allowed"""def __init__(self, previous, next, message):self.previous = previousself.next = nextself.message = message大多數的異常的名字都以"Error"結尾,就跟標準的異常命名一樣。七、定義清理行為(finally語句)
try 語句還有另外一個可選的子句,它定義了無論在任何情況下都會執行的清理行為。 例如:
>>> 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 / yexcept ZeroDivisionError:print("division by zero!")else:print("result is", result)finally:print("executing finally clause")>>> divide(2, 1)result is 2.0executing finally clause>>> divide(2, 0)division by zero!executing finally clause>>> divide("2", "1")executing finally clauseTraceback (most recent call last):File "<stdin>", line 1, in ?File "<stdin>", line 3, in divideTypeError: 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 總是會關閉。python標準異常
| 異常名稱 | 描述 |
|---|---|
| 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 | 用戶代碼生成的警告 |
新聞熱點
疑難解答