python之异常处理_Python之异常处理
異常對象
請大家運行如下代碼
a = 100/0
print(a)
就會發現解釋器顯示如下的錯誤提示
Traceback (most recent call last): File "xxxxxxxxxx.py", line 1, in
a = 100/0
ZeroDivisionError: division by zero
大家要學會看解釋器的報錯。
這就是解釋器向我們報告, 有一個 ZeroDivisionError 錯誤對象 或者說 異常對象 產生了。
這個 ZeroDivisionError 對象 代表的是一個除以0 的異常。 我們知道0是不能作為除數的。
因為這個問題,解釋器沒有辦法繼續執行后面的代碼了。所以程序就此結束執行了。
ZeroDivisionError就是一個異常對象的類,繼承自標準庫里面的 Exception 類。
Python標準庫中還有很多其他的異常類 都是繼承自標準庫里面的 Exception 類,代表各種不同類型的錯誤。
大家可以在命令行窗口 運行 Python 解釋器交互命令行,分別輸入如下代碼:
xxxx
會產生 NameError,表示xxxx沒有定義
dict1 = {1:1} print(dict1[2])
會產生 KeyError,表示該字典沒有key為2的元素
import xxxx
會產生 ModuleNotFoundError,表示找不到xxxx這樣的模塊
捕獲異常
解釋器執行代碼過程中,如果發生異常,就會導致解釋器沒法繼續按照正常流程往下執行代碼,所以解釋器會結束當前線程的執行。
如果執行的程序是個單線程的程序,整個程序執行就會結束了。
如果我們在編碼的時候,就預料到了某些代碼運行時可能出現某些異常,就可以使用 try...except... 這樣的方法來捕獲和處理異常。
比如,我們要開發程序,實現一個把用戶輸入的身高從英尺換算成米,如下所示
while True:
miles = input('請輸入英里數:')
km = int(miles) * 1.609344
print(f'等于{km}公里')
編寫這段代碼的時候, 我們就可以預料到,可能用戶會輸入非數字的字符,用int轉化就會出錯了,導致整個程序就退出了。
這時,我們就可以這樣寫
while True:
try:
miles = input('請輸入英里數:')
km = int(miles) * 1.609344
print(f'等于{km}公里')
except ValueError:
print('你輸入了非數字字符')
try 下面縮進的代碼出現異常時,解釋器會結束 try中 后續代碼的執行,并檢查這個異常的類型是否匹配后面的except 語句中聲明的類型。
如果匹配上,就認為該異常是預先有對應的處理方案的,就執行匹配的except下面縮進的代碼。從而不會結束當前線程。上面的例子中,執行 try 下面縮進的代碼時,如果用戶輸入了 hello 這樣的非數字, 就會在這行語句處
km = int(miles) * 1.609344
產生 ValueError 類型的異常, 解釋器就會去查看后面的 except 語句是否聲明了對 ValueError 異常的處理。
發現有, 就會執行后面縮進的代碼。也就是這句代碼
print('你輸入了非數字字符')
except 后面縮進的代碼 就是對這種類型錯誤 的一種處理。
既然程序已經知道如何處理這種問題, 就不需要結束執行,只需要執行完 處理代碼后, 進行原來正常的執行流程。
在這里,就是繼續 while True 循環。
如果我們開發程序的時候,估計某個代碼段中可能出現好幾種類型的異常,可以使用多個except 代碼段,分別捕獲多種類型的異常,如下
try:
choice = input('輸入你的選擇:')
if choice == '1':
100/0
elif choice == '2':
[][2]
except ZeroDivisionError: print ('出現 ZeroDivisionError') except IndexError : print ('出現 IndexError')
如果 輸入’1’, 則會產生 ZeroDivisionError 異常, 就會被 except ZeroDivisionError 捕獲,執行對應的代碼
print ('出現 ZeroDivisionError')
如果 輸入’2’, 則會產生 IndexError 異常, 就會被 except IndexError 捕獲,執行對應的代碼
print ('出現 IndexError')
獲取異常對象
我們使用except 語句匹配異常類型的時候, 可以使用as關鍵字,后面加一個變量名,如下所示:
try:
100/0
except ZeroDivisionError as e:
print (f'異常對象信息:{e}')
這樣,運行代碼的時候,當try中的語句產生異常對象時,就會 把產生的異常對象賦值給as后的變量。
上面的代碼,運行輸出
異常對象信息:division by zero
產生的異常對象賦值給了變量 e。
這樣我們就可以在后續的代碼中得到產生的異常對象的信息。
匹配所有異常
如果我們在寫一段代碼的時候,不知道這段代碼會拋出什么樣的異常,并且我們不希望程序因為異常而中止。
這時我們可以匹配所有類型的異常,這樣任何類型的異常發生都不會終止程序了。 如下:
try:
100/0
except Exception as e:
print('未知異常:', e)
因為所有的異常都是 Exception 的子類。 所以 Exception能匹配所有類型的異常。
except 為空,也可以匹配所有類型的異常,而且可以通過traceback庫,顯示異常的信息和異常產生處的函數調用棧的信息,如下
import traceback
try:
100/0
except:
print(traceback.format_exc())
上面的代碼會打印出導致異常的詳細的函數調用棧的信息,如下
Traceback (most recent call last):
File "xxxx/xxx.py", line 4, in
100/0
ZeroDivisionError: division by zero
自定義異常
異常類型都是 繼承自Exception的類,表示各種類型的錯誤。
我們也可以自己定義異常,比如我們寫一個用戶注冊的函數, 要求用戶輸入的電話號碼只能是中國的電話號碼,并且電話號碼中不能有非數字字符。
可以定義下面這兩種異常類型:
# 異常對象,代表電話號碼有錯誤的字符
class InvalidCharError(Exception):
pass
# 異常對象,代表電話號碼非中國號碼
class NotChinaTelError(Exception):
pass
定義了上面的異常,當用戶輸入電話號碼時,出現相應錯誤的時候,我們就可以使用raise 關鍵字來拋出對應的自定義異常
def register():
tel = input('請注冊您的電話號碼:')
# 如果有非數字字符
if not tel.isdigit():
raise InvalidCharError
# 如果不是以86開頭,則不是中國號碼
if not tel.startswith('86'):
raise NotChinaTelError
return tel
try:
ret = register()
except InvalidCharError:
print('電話號碼中有錯誤的字符')
except NotChinaTelError:
print('非中國手機號碼')
總結
以上是生活随笔為你收集整理的python之异常处理_Python之异常处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 太吾绘卷第一世攻略_建平中学高二数学周练
- 下一篇: centos7开启vnc服务_阿里云Ce