Python基础概念_10_异常处理
異常處理
11?異常處理
11.1?簡介
程序是在某個條件下實現某個功能的指令集,如果執行的環境發生了變化那么程序可能會出異常。比如實現一個打開文件的功能,我們在上章里都是直接打開文件,但實際執行時文件可能不存在。如果對這個異常我們沒有做處理,那么python會幫我們處理,不過顯然系統給的系統對用戶來說不是很友好,可讀性不高。而且在沒有加異常捕獲時,程序遇到異常就終止了。所以一般我們都要對異常進行捕獲,讓程序更健壯,能適應各種異常的情況。
程序異常示例:
f =open("G:\\tmp\\xiaodao1.txt", "r")?
f.read()?
print("繼續執行呢!")
執行結果:
Traceback (mostrecent call last):
? File "FileOperate.py", line 20, in<module>
??? f = open("D:\\tmp\\xiaodao1.txt","r")
FileNotFoundError:[Errno 2] No such file or directory: 'D:\\tmp\\xiaodao1.txt'
注:此例中如下的代碼在遇到異常時將不會被執行:
f.read()?
print ("繼續執行呢!")
11.2?處理異常
處理異常又成異常捕獲,一般我們是通過try/except語句。該語句是用來檢測try語句塊中的錯誤,從而讓except語句捕獲異常信息并處理。這樣當我們的程序出現異常并捕獲到后程序還是會繼續執行。所以上節的代碼我們修改如下:
try:
??? f = open("G:\\tmp\\xiaodao1.txt","r")?
??? f.read()?
exceptIOError:
??? print ("Error: 沒有找到文件或讀取文件失敗")
???
print("盡管有異常,捕獲后會繼續執行呢!")?
?
執行結果:
Error: 沒有找到文件或讀取文件失敗
盡管異常,捕獲后會繼續執行呢!
如上是個捕獲異常的簡單例子,接下來我們結合try/except的語法來詳細介紹下異常捕獲的常用處理處理方法。
11.2.1?tryexcept else語句
語法見下:
try:
? ??Normal execution block(代碼塊)
except A:
? ? ?Exception A handle(異常A的具體處理方法)
except B:
? ??Exception B handle(異常B的具體處理方法)
except:
? ??Other exception handle(其它異常的具體處理方法)
else:
? ? ?if no exception,get here(如果沒有異常則處理)
finally:
????final execution block (不論是否異常都會被執行到)?
執行順序說明:
正常時程序會執行try里面的Normal execution block,當出現異常時,則會中斷當前Normalexecution block中的執行跳轉到對應的異常處理塊里執行異常處理的代碼。python從第一個except X處開始查找,如果找到了對應的exception類型則進入該異常里的處理。如果沒有找到則直接進入except塊處進行處理。
注:
1)? 上面語法里的except塊是個可選項,如果代碼里沒有出現,該異常將會被提交給python進行默認處理,處理方式則是終止應用程序并打印提示信息。
2)? 異常里的代碼執行順序是 try-->exceptX-->except-->else-->finally。其中except是except X沒找到時執行,else是沒有異常時執行,finally是無論有沒有異常都會執行。
代碼示例:
?
如下是個鍵盤接受用戶輸入的程序
try:
??? text = input('請輸入些單詞')
exceptEOFError:
??? print('你為什么輸入個EOF(windows里按ctrl+z,linux里是ctrl+c)給我?')
exceptKeyboardInterrupt:
??? print('你輸出了取消鍵ctr+c')
else:
??? print('你輸入了 {0}'.format(text))
finally:
??? print('無論是否異常最終都會被執行finally!')
執行結果:
1)??????場景一輸入ctrl+z模擬程序終止
請輸入些單詞:^Z
你為什么輸入個EOF(windows里按ctrl+z,linux里是ctrl+c)給我?
無論是否異常最終都會被執行finally!
2)??????場景二輸入ctrl+c模擬終止輸入
請輸入些單詞:
你輸出了取消鍵ctr+c
無論是否異常最終都會被執行finally!
3)??????場景三正常輸入hello xiaodao
請輸入些單詞:hello xiaodao
你輸入了 hello xiaodao
無論是否異常最終都會被執行finally!
11.2.2?tryexcept語句
該異常捕獲語句是上述完整語句的簡化版。
代碼示例:
?
如下是個鍵盤接受用戶輸入的程序
try:
??? text = input('請輸入些單詞:')
except:
??? print('你的輸入有誤')
else:
??? print('你輸入了 {0}'.format(text))
finally:
??? print('無論是否異常最終都會被執行finally!')???
執行結果:
1)??????場景一輸入ctrl+z模擬程序終止
請輸入些單詞:^Z
你的輸入有誤
無論是否異常最終都會被執行finally!
2)??????場景二輸入ctrl+c模擬終止輸入
請輸入些單詞:
你的輸入有誤
無論是否異常最終都會被執行finally!
3)??????場景三輸入hello world
請輸入些單詞:hello world
你輸入了 hello world
無論是否異常最終都會被執行finally!
如果你想查看異常的詳細原因,還可以將異常記錄到一個文件里。修改后的代碼見下:
改善后代碼:
importtraceback
try:
??? text = input('請輸入些單詞:')
except:
??? print('你的輸入有誤,詳細錯誤信息,請查看c:\\inputerror.txt')
??? f=open("c:\\inputerror.txt",'a')?
??? traceback.print_exc(file=f)?
??? f.flush()?
??? f.close()
else:
??? print('你輸入了 {0}'.format(text))
finally:
??? print('無論是否異常最終都會被執行finally!')
?
執行結果:
請輸入些單詞:^Z
你的輸入有誤,詳細錯誤信息,請查看c:\inputerror.txt
無論是否異常最終都會被執行finally!
通過查看c:\inputerror.txt里的內容,我們知道這里是個EOFError。
Traceback (mostrecent call last):
? File "FileOperate.py", line 115, in<module>
??? text = input('請輸入些單詞:')
EOFError
11.2.3?tryfinally語句
該語句沒有對異常進行處理,即無論是否有異常都會正常執行但異常會被python捕獲到并終止程序。
try:
??? text = input('請輸入些單詞:')
finally:
??? print('無論是否異常最終都會被執行finally!')
print("程序異常后將不會執行,反之會顯示")
?
執行結果:
?
1)??????場景一輸入ctrl+z模擬程序終止
請輸入些單詞:^Z
無論是否異常最終都會被執行finally!
Traceback (mostrecent call last):
? File "FileOperate.py", line 129, in<module>
??? text = input('請輸入些單詞:')
EOFError
?
注:這里出現異常,最后一行的print函數沒有再執行。
?
2)??????場景一輸入hello world
請輸入些單詞:hellow world
無論是否異常最終都會被執行finally!
程序異常后將不會執行,反之會顯示
注:不建議這樣使用try except和try finally方式捕獲異常,因為更細分的異常沒有個個捕獲。
11.3?拋出異常
如果我們知道程序中會有一個很顯著的異常時可以使用 raise 語句拋出它。比方0不能做分母。
代碼示例:
defdivide(x, y):
??? if y == 0 :?
??????? raise ZeroDivisionError('The zero is notallow')?
??? return x / y
a=input("請輸入個數字:")
b=input("請輸入另外個數字:")
print("除法結果:\t"+str(divide(int(a),int(b))))
執行結果:
1)??????場景一輸入0作為分母
請輸入個數字:10
請輸入另外個數字:0
Traceback (most recent call last):
? File"FileOperate.py", line 159, in <module>
??? print("除法結果:\t"+str(divide(int(a),int(b))))
? File"FileOperate.py", line 155, in divide
??? raiseZeroDivisionError('The zero is not allow')
ZeroDivisionError:The zero is not allow
2)??????場景二輸入正常的數字
請輸入個數字:10
請輸入另外個數字:20
除法結果:?????? 0.5
11.4?自定義異常
自定義異常是通過創建一個新的exception類來擁有自己的異常。異常通過需要繼承自 Exception 類。
代碼示例:
這里定義了一個自己的異常,會記錄外部傳來的value值。主程序里當輸入數字小于10時觸發自定義異常。
classMyError(Exception):
??????? def __init__(self, value):
??????????? self.value = value
????? ??def __str__(self):
??????????? return repr(self.value)
???????
a=input("pleaseinput a num:")
ifint(a)<10:
??? try:
??????? raise MyError(a)
??? except MyError as e:
??????? ?print('我自定義的異常觸發了,輸入的value小于10,它的值是:', e.value)
else:
??? print("查詢正常執行!")
執行結果:
1)??????場景一輸入5
please input a num:5
我自定義的異常觸發了,輸入的value小于10,它的值是: 5
2)??????場景二輸入15
please input a num:18
查詢正常執行!
11.5?系統定義異常
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 | 語法錯誤 |
| 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 | 用戶代碼生成的警告 |
11.6?總結
這一章我們已經討論了try..except和try..finally 語句的用法,同時也學習了如何創建我們自己的異常類型以及如何引發異常。接下來,我們將探索Python 標準庫。
總結
以上是生活随笔為你收集整理的Python基础概念_10_异常处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 科创板对标是什么意思
- 下一篇: Python基础概念_11_标准库