1、異常概念
定義:程式在執行過程當中,不可避免的會出現一些錯誤,可能經常看到的報錯資訊,例如:NameError
、TypeError
、 ValueError
等,這些都是異常。
程式執行過程中,一旦出現異常將會導致程式立即終止,異常以後的程式碼全部都不會執行。所以當Python程式發生異常時,我們需要捕獲並處理異常,否則程式就會終止執行,影響程式的正常執行。
2、瞭解異常
當檢測到一個錯誤時,直譯器就無法繼續執行了,會出現一些錯誤的提示到控制檯,這就是所謂的"異常"。
例如:以r
方式開啟一個不存在的檔案,就會丟擲異常,我們在控制檯中就能夠看到。
open('test.txt', 'r')
像上面這種情況,我們在編寫程式碼的時候,我們不確定一個語句是否一定會正確執行,這個時候就可以把這句可能出現的問題的程式碼,放入到異常語句中。
因為異常語句會嘗試執行一行或一段可能發生錯誤的程式碼,萬一發生錯誤可以執行另外一行或一段一定可以執行的程式碼,從而替代有錯誤的程式碼。以達到讓程式不報錯,可以繼續向下執行程式。
總結:
Python程式執行時出現異常,目的並不是讓我們的程式直接終止。
而是Python是希望在出現異常時,我們可以編寫程式碼來對異常進行處理。
3、異常的寫法
(1)語法
try:
可能發生錯誤的程式碼
except:
如果出現異常執行的程式碼(出現錯誤以後的處理方式)
(2)快速體驗
需求:嘗試以r
模式開啟檔案,如果檔案不存在,則以w
方式開啟。
try:
f = open('test.txt', 'r')
except:
f = open('test.txt', 'w')
(3)捕獲指定異常
1)語法
try:
可能發生錯誤的程式碼
except 異常型別:
如果捕獲到該異常型別執行的程式碼
說明:如果我們執行的程式碼有錯誤,且錯誤型別和
except
指定的異常型別一致,則執行匹配型別異常下定義的程式碼。
總結:
- 如果
except
後不跟任何的內容,則此時它會捕獲到所有的異常。- 如果在
except
後跟著一個異常的型別,那麼此時它只會捕獲該型別的異常。
2)體驗
"""
需求:嘗試執行列印num,捕獲異常型別NameError,
如果捕獲到這個異常型別,執行列印:你的變數沒有被定義
"""
# 結果:你的變數沒有被定義
try:
print(num)
except NameError:
print('你的變數沒有被定義')
注意:
- 如果嘗試執行的程式碼的異常型別和要捕獲的異常型別不一致,則無法捕獲異常。
- 一般
try
下方只放一行嘗試執行的程式碼。
3)捕獲多個指定異常。
有時候我們編寫程式碼的時候,並不確定一行程式碼可能丟擲哪種異常型別,可能就會多寫幾種異常型別。
當捕獲多個異常時,可以把要捕獲的異常型別的名字,統一放到except
後,並使用元組的方式進行書寫。
try:
print(1/0)
except (NameError, ZeroDivisionError):
print('有錯誤')
只要嘗試執行的異常程式碼,所丟擲來的異常型別,和
except
後定義在元組中的任一異常型別相匹配,都能被捕獲到。
不同型別的異常型別也可以分開寫,如下:
try:
print(10/0)
except NameError:
print('出現 NameError 異常')
except ZeroDivisionError:
print('出現 ZeroDivisionError 異常')
except IndexError:
print('出現 IndexError 異常')
4)何為異常型別何為異常描述資訊。
在控制檯檢視的異常資訊中,如NameError: name 'num' is not defined
,
冒號前NameError
,顯示的就是異常型別。
冒號後name 'num' is not defined
,顯示的就是異常描述資訊。
5)捕獲異常描述資訊。
try:
print(num)
except (NameError, ZeroDivisionError) as result:
print(result)
# 或者
try:
print(10/0)
except NameError as e:
print('異常型別',e)
except ZeroDivisionError as e:
print('異常型別',e)
except IndexError as e:
print('異常型別',e)
as
是一個關鍵字,as
關鍵字後的變數就是捕獲到的異常的描述資訊,變數名是可以自定義的。
6)捕獲所有異常。
Exception
是所有程式異常類的父類,所以如果except
後跟的是Exception
,也會捕獲到所有的異常。
# 1.捕獲所有異常
try:
print(num)
except Exception:
print("捕獲異常了")
# 或者不寫Exception
try:
print(num)
except:
print("捕獲異常了")
# 2.捕獲所有異常資訊
try:
print(num)
except Exception as result:
print(result)
(4)異常中的else
else
表示的是如果沒有異常要執行的程式碼。
try:
print(1)
except Exception as result:
print(result)
else:
print('我是else,是沒有異常的時候執行的程式碼')
(5)異常中的finally
finally
表示的是,無論是否異常都要執行的程式碼。也就是說,不管前邊程式碼是否正確執行,都必須只要執行的程式碼,就寫在finally
中。例如關閉檔案。
try:
f = open('test.txt', 'r')
except Exception as result:
f = open('test.txt', 'w')
else:
print('沒有異常,真開心')
finally:
# 一般用於關閉所有開啟的資源
f.close()
(6)總結
異常處理的完整結構,如下所示:
try語句
try:
程式碼塊(可能出現錯誤的語句)
except 異常型別 as 異常名:
程式碼塊(出現錯誤以後的處理方式)
except 異常型別 as 異常名:
程式碼塊(出現錯誤以後的處理方式)
except 異常型別 as 異常名:
程式碼塊(出現錯誤以後的處理方式)
else:
程式碼塊(沒出錯時要執行的語句)
finally:
程式碼塊(該程式碼塊總會執行)
說明:
try
是必須寫的,可以將可能出錯的程式碼放入到try
語句中,這樣如果程式碼沒有錯誤,則會正常執行。如果出現錯誤,則會執行expect
子句中的程式碼,這樣我們就可以通過程式碼來處理異常, 避免因為一個異常導致整個程式的終止 。else
語句有沒有都行。except
和finally
至少有一個 。