Python的異常概念介紹以及處理
一、什么是異常處理
定義:異常處理就是我們在寫Python時,經(jīng)??吹降膱箦e信息,例如;NameError TypeError ValueError等,這些都是異常。
異常是一個事件,改事件會在程序執(zhí)行過程中發(fā)生,影響程序的正常執(zhí)行,一般情況下,在python中無法處理程序時就會發(fā)生異常,異常時Python的一個對象,表示一個錯誤,當(dāng)Python腳本發(fā)生異常時,我們需要捕獲并處理異常,否則程序就會終止執(zhí)行。
二、異常處理
當(dāng)Python腳本出現(xiàn)異常的時候我們怎么處理那?
就如我們使用的工具出現(xiàn)了一點毛病,我們可以想辦法修理好它,程序也是一樣,之前的前輩們經(jīng)過不斷的積累與思考,創(chuàng)造了很多好得方法處理程序中出現(xiàn)的異常,本章我們就講一下使用try語句處理異常。
首先我們來說一下try語句的語法:
try語句與except 相結(jié)合使用,此語句用來檢測try語句塊中的錯誤,從而讓except語句捕獲異常信息并處理,如果不想在發(fā)生異常時結(jié)束程序,只需要在try語句中捕獲異常即可
try: <代碼塊> except <異常名字> print(‘語句') 實例如下: def func(): try: a = x/y print('a=',a) return a eccept Exception: print('程序出現(xiàn)異常,異常信息:被除數(shù)為0')
三、拋出異常
在Python中使用raise語句拋出一個指定的異常,我們可以使用類或?qū)嵗齾?shù)調(diào)用raise語句引發(fā)異常。
實例如下:
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語句處理多個異常,語法如下:
try: <語句> except <異常名字>: print(‘異常說明') except <異常名字>: print(‘異常說明') try語句的工作方式如下: 首次執(zhí)行try中語句塊,如果沒有發(fā)生異常,則忽略except中的字句,try語句中的代碼塊執(zhí)行后結(jié)束。如果try語句中的代碼塊出現(xiàn)異常,try中的剩余語句則會被忽略, 如果異常和eccept中的異常名字一直,相應(yīng)的except語句就會被執(zhí)行。如果一個異常也沒有匹配,這個異常就會傳遞給上層的try語句中,一個語句可能包含第一個except語句, 分別處理不同的異常,但是最多只有一個分支會執(zhí)行。 try: #a #1/0 dic = {1:2} dic[3] except NameError: print('名字沒有定義,報錯了') except ZeroDivisionError: print('0不能當(dāng)做除數(shù),報錯了') except KeyError: print('沒有這個key')
五、異常中else
我們?nèi)绻绦驁?zhí)行完異常后還想做其他的事情怎么辦?
這時我們就可以用到異常中的else了,具體語法如下:
try: <語句> except <異常名字> : <語句> except <異常名字>: <語句> else: <語句> #(try語句中沒有異常后執(zhí)行此段代碼) 如果在try語句中執(zhí)行沒有發(fā)生異常,就會執(zhí)行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)
六、用戶自定義異常
你可以通過創(chuàng)建一個新的exception類來擁有自己的異常。異常應(yīng)該繼承自 Exception 類,或者直接繼承,或者間接繼承,例如:
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__() 被覆蓋。 當(dāng)創(chuàng)建一個模塊有可能拋出多種不同的異常時,一種通常的做法是為這個包建立一個基礎(chǔ)異常類,然后基于這個基礎(chǔ)類為不同的錯誤情況創(chuàng)建不同的子類: 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 大多數(shù)的異常的名字都以"Error"結(jié)尾,就跟標(biāo)準(zhǔn)的異常命名一樣。
七、定義清理行為(finally語句)
try 語句還有另外一個可選的子句,它定義了無論在任何情況下都會執(zhí)行的清理行為。 例如:
>>> try: ... raise KeyboardInterrupt ... finally: ... print('Goodbye, world!') ... Goodbye, world! Traceback (most recent call last): File "<stdin>", line 2, in <module> KeyboardInterrupt 以上例子不管 try 子句里面有沒有發(fā)生異常,finally 子句都會執(zhí)行。 如果一個異常在 try 子句里(或者在 except 和 else 子句里)被拋出,而又沒有任何的 except 把它截住,那么這個異常會在 finally 子句執(zhí)行后再次被拋出。 下面是一個更加復(fù)雜的例子(在同一個 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' 預(yù)定義的清理行為 一些對象定義了標(biāo)準(zhǔn)的清理行為,無論系統(tǒng)是否成功的使用了它,一旦不需要它了,那么這個標(biāo)準(zhǔn)的清理行為就會執(zhí)行。 這面這個例子展示了嘗試打開一個文件,然后把內(nèi)容打印到屏幕上: for line in open("myfile.txt"): print(line, end="") 以上這段代碼的問題是,當(dāng)執(zhí)行完畢后,文件會保持打開狀態(tài),并沒有被關(guān)閉。 關(guān)鍵詞 with 語句就可以保證諸如文件之類的對象在使用完之后一定會正確的執(zhí)行他的清理方法: with open("myfile.txt") as f: for line in f: print(line, end="") 以上這段代碼執(zhí)行完畢后,就算在處理過程中出問題了,文件 f 總是會關(guān)閉。
python標(biāo)準(zhǔn)異常
異常名稱 | 描述 |
---|---|
BaseException | 所有異常的基類 |
SystemExit | 解釋器請求退出 |
KeyboardInterrupt | 用戶中斷執(zhí)行(通常是輸入^C) |
Exception | 常規(guī)錯誤的基類 |
StopIteration |
迭代器沒有更多的值 |
GeneratorExit | 生成器(generator)發(fā)生異常來通知退出 |
StandardError | 所有的內(nèi)建標(biāo)準(zhǔn)異常的基類 |
ArithmeticError | 所有數(shù)值計算錯誤的基類 |
FloatingPointError | 浮點計算錯誤 |
OverflowError | 數(shù)值運算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有數(shù)據(jù)類型) |
AssertionError | 斷言語句失敗 |
AttributeError | 對象沒有這個屬性 |
EOFError | 沒有內(nèi)建輸入,到達EOF 標(biāo)記 |
EnvironmentError | 操作系統(tǒng)錯誤的基類 |
IOError | 輸入/輸出操作失敗 |
OSError | 操作系統(tǒng)錯誤 |
WindowsError | 系統(tǒng)調(diào)用失敗 |
ImportError | 導(dǎo)入模塊/對象失敗 |
LookupError | 無效數(shù)據(jù)查詢的基類 |
IndexError | 序列中沒有此索引(index) |
KeyError | 映射中沒有這個鍵 |
MemoryError | 內(nèi)存溢出錯誤(對于Python 解釋器不是致命的) |
NameError | 未聲明/初始化對象 (沒有屬性) |
UnboundLocalError | 訪問未初始化的本地變量 |
ReferenceError | 弱引用(Weak reference)試圖訪問已經(jīng)垃圾回收了的對象 |
RuntimeError | 一般的運行時錯誤 |
NotImplementedError | 尚未實現(xiàn)的方法 |
SyntaxError | Python 語法錯誤 |
IndentationError | 縮進錯誤 |
TabError | Tab 和空格混用 |
SystemError | 一般的解釋器系統(tǒng)錯誤 |
TypeError | 對類型無效的操作 |
ValueError | 傳入無效的參數(shù) |
UnicodeError | Unicode 相關(guān)的錯誤 |
UnicodeDecodeError | Unicode 解碼時的錯誤 |
UnicodeEncodeError | Unicode 編碼時錯誤 |
UnicodeTranslateError | Unicode 轉(zhuǎn)換時錯誤 |
Warning | 警告的基類 |
DeprecationWarning | 關(guān)于被棄用的特征的警告 |
FutureWarning | 關(guān)于構(gòu)造將來語義會有改變的警告 |
OverflowWarning | 舊的關(guān)于自動提升為長整型(long)的警告 |
PendingDeprecationWarning | 關(guān)于特性將會被廢棄的警告 |
RuntimeWarning | 可疑的運行時行為(runtime behavior)的警告 |
SyntaxWarning | 可疑的語法的警告 |
UserWarning | 用戶代碼生成的警告 |
相關(guān)文章
Android消息推送:手把手教你集成小米推送(附demo)
本篇文章主要介紹了Android消息推送:手把手教你集成小米推送,非常具有實用價值,需要的朋友可以參考下。2016-12-12Android開發(fā)之HttpClient異步請求數(shù)據(jù)的方法詳解【附demo源碼下載】
這篇文章主要介紹了Android開發(fā)之HttpClient異步請求數(shù)據(jù)的方法,結(jié)合實例形式較為詳細的分析了Android HttpClient異步請求數(shù)據(jù)的相關(guān)操作技巧,并附帶完整demo源碼供讀者下載參考,需要的朋友可以參考下2017-11-11Android 自定義view和屬性動畫實現(xiàn)充電進度條效果
近期項目中需要使用到一種類似手機電池充電進度的動畫效果,以前沒學(xué)屬性動畫的時候,是用圖片+定時器的方式來完成的,下面給大家分享android自定義view和屬性動畫實現(xiàn)充電進度條2016-12-12Android計時器的三種實現(xiàn)方式(Chronometer、Timer、handler)
這篇文章主要介紹了Android計時器的三種實現(xiàn)方式,Chronometer、Timer、handler計時器的實現(xiàn)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11Kotlin新手基礎(chǔ)學(xué)習(xí)之Elvis操作符
Kotlin 是一種在 Java 虛擬機上運行的靜態(tài)類型編程語言,被稱之為 Android 世界的Swift,由 JetBrains 設(shè)計開發(fā)并開源,下面這篇文章主要給大家介紹了關(guān)于Kotlin新手基礎(chǔ)學(xué)習(xí)之Elvis操作符的相關(guān)資料,需要的朋友可以參考下。2017-12-12淺談Android Studio如何Debug對應(yīng)so文件C/C++代碼
本篇文章主要介紹了淺談Android Studio如何Debug對應(yīng)so文件C/C++代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12Android中ViewPager組件的基本用法及實現(xiàn)圖片切換的示例
這篇文章主要介紹了Android中ViewPager組件的基本用法及實現(xiàn)圖片切換的示例,ViewPager主要被用來實現(xiàn)滑動切換效果,需要的朋友可以參考下2016-03-03