異常就是程序運行時發生錯誤的信號,Python遇到錯誤後,會引起異常。若是異常對象並未被處理或捕捉,則程序就會用所謂的回溯(Traceback,一種錯誤信息)來終止執行。python
爲了保證程序的健壯性與容錯性,即在遇到錯誤時程序不會崩潰,咱們須要對異常進行處理。git
下面編寫一個一樣功能的代碼,對比作異常處理和不作異常處理的區別。程序員
'''不作異常處理''' num = int(input('請輸入數字>>>')) #當輸入的非數字時,則會觸發異常,終止程序執行,下面的代碼不會被執行,致使程序崩潰。 print('你輸入的整數是:{}'.format(num))
若是發生的錯誤是可預知的,咱們能夠用if語句進行處理:在錯誤發生以前進行預防。網絡
'''作異常處理''' num = input('請輸入數字>>>') #當輸入的非數字時,則會觸發異常,終止程序執行,下面的代碼不會被執行,致使程序崩潰。 if num.isdigit(): print('你輸入的整數是:{}'.format(int(num))) else: print('你輸入的不徹底是數字。')
在全部的程序中,都會遇到異常,有些異常是代碼編寫的時候產生的,在前期過程當中可能會直接致使程序沒法運行。這一類的異常,在編寫代碼的時候,程序能夠直接排查修改。但有些異常,是在程序運行過程當中產生的,多是與用戶交互獲取的數據沒法識別,也或者是網絡請求失敗致使程序沒法繼續等等不可預知的異常。爲了防止程序崩潰,這一類的錯誤,就須要程序員在編寫的時候提早考慮到並進行相應的異常處理。每一門語言基本都有本身相應的異常防護機制,python尤爲如此,不只給了錯誤調試語句,還提供了龐大的內置異常類,讓咱們能夠精準的針對不一樣異常給出不一樣的處理方式。編碼
異常名稱 | 描述 |
AssertionError | 斷言語句失敗 |
AttributeError | 對象沒有這個屬性 |
EOFError | 沒有內建輸入,到達EOF 標記 |
EnvironmentError | 操做系統錯誤的基類 |
IOError | 輸入/輸出操做失敗 |
WindowsError | 系統調用失敗 |
RuntimeError | 通常的運行時錯誤 |
OverflowWarning | 舊的關於自動提高爲長整型(long)的警告 |
OSError | 操做系統錯誤 |
Warning | 警告的基類 |
DeprecationWarning | 關於被棄用的特徵的警告 |
FutureWarning | 關於構造未來語義會有改變的警告 |
ImportError | 導入模塊/對象失敗 |
LookupError | 無效數據查詢的基類 |
IndexError | 序列中沒有此索引(index) |
MemoryError | 內存溢出錯誤(對於Python 解釋器不是致命的) |
NameError | 未聲明/初始化對象 (沒有屬性) |
OverflowError | 數值運算超出最大限制 |
SyntaxWarning | 可疑的語法的警告 |
ZeroDivisionError | 當除運算或模零在全部數值類型運算時引起 |
PendingDeprecationWarning | 關於特性將會被廢棄的警告 |
RuntimeWarning | 當生成的錯誤不屬於任何類別時引起 |
UnicodeEncodeError | Unicode 編碼時錯誤 |
UserWarning | 用戶代碼生成的警告 |
UnicodeTranslateError | Unicode 轉換時錯誤 |
UnboundLocalError | 訪問未初始化的本地變量 |
ReferenceError | 弱引用試圖訪問已經垃圾回收了的對象 |
KeyError | 映射中沒有這個鍵 |
異常:是指在程序執行過程當中發生的一個事件,會影響程序的正常運行,當程序運行時系統接受到異常對象時,會尋找能處理這異常的代碼並把當前異常對象交給其處理。因此通常須要進行捕獲異常並處理。異常的捕獲使用try/except/finally語句進行捕獲操做。spa
處理異常的語法結構:操作系統
'''異常處理''' try: '''被檢測的代碼塊''' num = input('請輸入數字>>>') print('你輸入的整數是:{}'.format(int(num))) except: #若不寫異常類型,則默認捕獲全部異常。 print('你輸入的不徹底是數字') #可多分支捕獲不一樣異常類型,進行相應的異常處理。 try: '''被檢測的代碼塊''' num = input('請輸入數字>>>') print('你輸入的整數是:{}'.format(int(num))) except TypeError: '''若是捕獲到TypeError,就執行這個位置的邏輯''' print('捕獲到TypeError時的處理邏輯') except ValueError as e: print(e) else: print('被檢測代碼正常運行,就執行這個位置的邏輯') finally: print('無論被檢測代碼是否有異常,該邏輯代碼塊都要執行,一般是進行清理工做') #可經過因此異常的基類BaseException,捕獲全部異常,經過常規錯誤的基類Exception,捕獲常規錯誤。 try: num = input('請輸入數字>>>') print('你輸入的整數是:{}'.format(int(num))) except BaseException: print('你輸入的不徹底是數字')
除了不可控的異常出現以外,有些代碼須要特定的運行條件,那麼,咱們能夠認爲拋出異常。python中拋異常的方式有兩種,斷言,或者raise語句。其中,斷言須要斷定條件,而raise是直接後接須要拋出的異常類型。兩者應用場合在個人理解中略有分別,斷言經常使用於根據條件成立來決定拋異常的與否,一般用於爲接下來執行的代碼正常運行從而進行數據校驗。例如,一個變量初始值爲空,在程序運行到一半它從網絡獲取數據,若是沒有數據,那麼,程序沒法執行。就可使用斷言來斷定變量是否爲空,若是爲空,則直接拋異常,並給出告警。固然,raise能夠實現一樣功能,不過它須要一個if判別。所以,在代碼使用上來說,斷言更爲簡潔,而且它也能被exception捕獲。咱們首先來看下斷言機制。調試
try: num = eval(input('請輸入一個結果等於9的表達式:')) except BaseException: print('你輸入的表達式不規範') else: """斷言關鍵字使用,後接斷定條件,若是條件成立,則無異常。不成立,拋AssertionError異常。<br>用","分割,後接給出的告警信息。告警信息也能夠省略""" assert num == 9, "腦子是個好東西,我但願你有一個。好好計算!" print("你真聰明!")
程序的執行過程當中如出現異常事件,能夠生成一個異常對象,斷言的語句用於已知的條件調試相對簡潔。但有些異常時python定義的異常類裏面存在的,爲了方便快捷,咱們能夠直接拋出,無需定義異常信息,這時就須要raise來解決了。code
raise NameError("name error!")#拋出一個NameError異常,能夠給一個打印信息,也能夠不給 #常規自定義具體異常信息應該儘可能拋Exception類 這裏僅作其餘類示範。 print("然而並無錯誤!") #拋出異常後嘗試打印點神馬
如上,raise能夠直接拋出python自帶的異常類,一看就知道哪裏出了錯誤,因此若是不須要條件斷定的是自定義異常信息,儘可能拋Exception類。這樣不至於混淆異常信息。以上代碼都立足於功能示範,在實際使用中,一旦拋出異常,程序就會崩潰。因此常規的拋異常大多用於代碼調試。若是是爲了預防未知信息,拋異常應該出現try--except語句的try下屬代碼模塊,而後用except捕獲,再給出相應的解決方案。orm
python容許你根據需求定義本身的異常類,但必須繼承所異常類的基類BaseException。
class EgonException(BaseException): def __init__(self,msg): self.msg=msg def __str__(self): return self.msg try: raise EgonException('類型錯誤') except EgonException as e: print(e)