異常處理
===
-
異常的定義
程序執(zhí)行過程中出現(xiàn)問題導(dǎo)致程序無法執(zhí)行
異常的分類:
程序遇到邏輯或算法錯(cuò)誤
運(yùn)行過程中計(jì)算機(jī)錯(cuò)誤:內(nèi)存不夠或者io錯(cuò)誤
異常的步驟:
異常產(chǎn)生谈为,檢查到錯(cuò)誤且解釋器認(rèn)為是異常脓规,拋出異常
異常處理卒落,異常處理瓣颅,截獲異常弧岳,系統(tǒng)忽略或者終止程序處理異常
-
常見的異常
- AttributeError 試圖訪問一個(gè)對(duì)象沒有的屬性化撕,比如foo.x几晤,但是foo沒有屬性x
- IOError 輸入/輸出異常;基本上是無法打開文件
- ImportError 無法引入模塊或包侯谁;基本上是路徑問題或名稱錯(cuò)誤
- IndentationError 語法錯(cuò)誤(的子類) 锌仅;代碼沒有正確對(duì)齊
- IndexError 下標(biāo)索引超出序列邊界,比如當(dāng)x只有三個(gè)元素墙贱,卻試圖訪問x[5]
- KeyError 試圖訪問字典里不存在的鍵
- KeyboardInterrupt Ctrl+C被按下
- NameError 嘗試訪問一個(gè)沒有申明的變量
- SyntaxError Python代碼非法热芹,代碼不能編譯(個(gè)人認(rèn)為這是語法錯(cuò)誤,寫錯(cuò)了)
- TypeError 傳入對(duì)象類型與要求的不符合
- UnboundLocalError 試圖訪問一個(gè)還未被設(shè)置的局部變量惨撇,基本上是由于另有一個(gè)同名的全局變量伊脓,導(dǎo)致你以為正在訪問它
- ValueError 傳入一個(gè)調(diào)用者不期望的值,即使值的類型是正確的
-
所有的異常
異常名稱 描述 BaseException 所有異常的基類 SystemExit 解釋器請(qǐng)求退出 KeyboardInterrupt 用戶中斷執(zhí)行(通常是輸入^C) Exception 常規(guī)錯(cuò)誤的基類 StopIteration 迭代器沒有更多的值 GeneratorExit 生成器(generator)發(fā)生異常來通知退出 StandardError 所有的內(nèi)建標(biāo)準(zhǔn)異常的基類 ArithmeticError 所有數(shù)值計(jì)算錯(cuò)誤的基類 FloatingPointError 浮點(diǎn)計(jì)算錯(cuò)誤 OverflowError 數(shù)值運(yùn)算超出最大限制 ZeroDivisionError 除(或取模)零 (所有數(shù)據(jù)類型) AssertionError 斷言語句失敗 AttributeError 對(duì)象沒有這個(gè)屬性 EOFError 沒有內(nèi)建輸入,到達(dá)EOF 標(biāo)記 EnvironmentError 操作系統(tǒng)錯(cuò)誤的基類 IOError 輸入/輸出操作失敗 OSError 操作系統(tǒng)錯(cuò)誤 WindowsError 系統(tǒng)調(diào)用失敗 ImportError 導(dǎo)入模塊/對(duì)象失敗 LookupError 無效數(shù)據(jù)查詢的基類 IndexError 序列中沒有此索引(index) KeyError 映射中沒有這個(gè)鍵 MemoryError 內(nèi)存溢出錯(cuò)誤(對(duì)于Python 解釋器不是致命的) NameError 未聲明/初始化對(duì)象 (沒有屬性) UnboundLocalError 訪問未初始化的本地變量 ReferenceError 弱引用(Weak reference)試圖訪問已經(jīng)垃圾回收了的對(duì)象 RuntimeError 一般的運(yùn)行時(shí)錯(cuò)誤 NotImplementedError 尚未實(shí)現(xiàn)的方法 SyntaxError Python 語法錯(cuò)誤 IndentationError 縮進(jìn)錯(cuò)誤 TabError Tab 和空格混用 SystemError 一般的解釋器系統(tǒng)錯(cuò)誤 TypeError 對(duì)類型無效的操作 ValueError 傳入無效的參數(shù) UnicodeError Unicode 相關(guān)的錯(cuò)誤 UnicodeDecodeError Unicode 解碼時(shí)的錯(cuò)誤 UnicodeEncodeError Unicode 編碼時(shí)錯(cuò)誤 UnicodeTranslateError Unicode 轉(zhuǎn)換時(shí)錯(cuò)誤 Warning 警告的基類 DeprecationWarning 關(guān)于被棄用的特征的警告 FutureWarning 關(guān)于構(gòu)造將來語義會(huì)有改變的警告 OverflowWarning 舊的關(guān)于自動(dòng)提升為長(zhǎng)整型(long)的警告 PendingDeprecationWarning 關(guān)于特性將會(huì)被廢棄的警告 RuntimeWarning 可疑的運(yùn)行時(shí)行為(runtime behavior)的警告 SyntaxWarning 可疑的語法的警告 UserWarning 用戶代碼生成的警告
-
如何處理異常
num2=input('>>: ') #輸入一個(gè)字符串試試 int(num2)
用常規(guī)方法解決
num1=input('>>: ') #輸入一個(gè)字符串試試 if num1.isdigit(): int(num1) #我們的正統(tǒng)程序放到了這里,其余的都屬于異常處理范疇 elif num1.isspace(): print('輸入的是空格,就執(zhí)行我這里的邏輯') elif len(num1) == 0: print('輸入的是空,就執(zhí)行我這里的邏輯') else: print('其他情情況,執(zhí)行我這里的邏輯')
-
異常處理格式
try: <語句> #運(yùn)行別的代碼 except <異常類型>: <語句> #如果在try部份引發(fā)了'name'異常 # python2 和 3 處理 except 子句的語法有點(diǎn)不同魁衙,需要注意报腔; # python2 用的是‘,’ 而三用的是 ‘a(chǎn)s’ except <異常類型> as <數(shù)據(jù)>: <語句> #如果引發(fā)了'name'異常剖淀,獲得附加的數(shù)據(jù) else: <語句> #如果沒有異常發(fā)生
例如
try: print(y) except NameError as e: print("變量名沒有定義的錯(cuò)誤信息:",e) else: print('沒有發(fā)生異常')
同時(shí)有else和finally語句
```
try:
y=0
print(y)
except NameError as e:
print("Oops! That was no valid number. Try again...",e)
else:
'''保護(hù)不拋出異常的代碼'''
print('我必須在finally 上面纯蛾,沒有發(fā)生異常就執(zhí)行')
finally:
print('不管有沒有發(fā)生異常都會(huì)執(zhí)行')
```
**異常類只能用來處理指定的異常情況,如果非指定異常則無法處理纵隔。(異常是由程序的錯(cuò)誤引起的翻诉,語法上的錯(cuò)誤跟異常處理無關(guān)炮姨,必須在程序運(yùn)行前就修正)**
-
多分支結(jié)構(gòu)
try: print(y) print('ss'+y) except RuntimeError as e: print("Oops! RuntimeError. Try again...",e) except TypeError as e: print("Oops! TypeError. Try again...",e) except NameError as e: print("Oops! NameError. Try again...",e) except ValueError as e: print("Oops! ValueError. Try again...",e) except: print("Unexpected error:", sys.exc_info()[0])
異常只會(huì)捕獲一次
也可以這么寫:
try: x = int(input("Please enter a number: ")) break except (RuntimeError, TypeError, NameError,ValueError): print("Oops! That was no valid number. Try again...")
萬能異常
在python的異常中,有一個(gè)萬能異常:Exception碰煌,他可以捕獲任意異常s1 = 'hello' try: int(s1) except Exception as e: '丟棄或者執(zhí)行其他邏輯' print(e)
-
raise主動(dòng)觸發(fā)異常
我們可以使用raise語句自己觸發(fā)異常raise語法格式如下:
raise [Exception [, args [, traceback]]]
語句中Exception是異常的類型(例如舒岸,NameError)參數(shù)是一個(gè)異常參數(shù)值。該參數(shù)是可選的芦圾,如果不提供蛾派,異常的參數(shù)是"None"。最后一個(gè)參數(shù)是可選的(在實(shí)踐中很少使用)个少,如果存在洪乍,是跟蹤異常對(duì)象。
try: raise TypeError('我是故意的') except RuntimeError as e: print("Oops! RuntimeError. Try again...",e) except TypeError as e: print("Oops! TypeError. Try again...",e) except NameError as e: print("Oops! NameError. Try again...",e) except ValueError as e: print("Oops! ValueError. Try again...",e)
-
自定義異常
class MyException(RuntimeError): def __index__(self,arg): self.args=arg try: raise MyException('OH,NO!') except MyException as e: print(e)
class MyException(RuntimeError): def __index__(self,arg): self.args=arg try: print(y) raise MyException('OH,NO!') except MyException as e: print(e) except NameError as e: print(e)
自定義異成运悖可以和系統(tǒng)異常一起工作
異常被其他異常攔截
class MyException(RuntimeError): def __index__(self,arg): self.args=arg try: # print(y) raise MyException('OH,NO!') except Exception as e: print('HERE',e) except MyException as e: print(e) except NameError as e: print(e)
綜合案例
import sys #自定義異常處理類典尾,繼承Exception類 class CustomInputException(Exception): '''a user-defined exception class ''' def __init__(self,length,atleast): Exception.__init__(self) self.length=length self.atleast=atleast try: s = input('Enter something --> ') if len(s)<3: # raise可以觸發(fā)自定義異常 raise CustomInputException(len(s),3) except EOFError: print('\nWhy did you do an EOF on me?') sys.exit() # exit the program except CustomInputException as x: print ('\n自定義異常類被觸發(fā),原因:輸入字長(zhǎng)度為:%d,\ 輸入字符串長(zhǎng)度必須大于%d'%(x.length,x.atleast)) # here, we are not exiting the program except: print('\nSome error/exception occurred.') # here, we are not exiting the program else: print('沒有發(fā)生異常') print('Done')