try-except
寫程式碼過程中難免會出現異常,比如:
執行 a=10/0 時會提示:ZeroDivisionError: division by zero
直接執行 a 會提示: NameError: name 'a' is not defined
執行 import mokuai (模組庫中沒有的模組) 會提示: ModuleNotFoundError: No module named 'mokuai'
這些錯誤型別如ZeroDivisionError、NameError、ModuleNotFoundError等都是繼承自Python標準庫裡的Exception類中的異常物件類,而程式在執行過程中報出這些錯誤時會影響程式後續的執行,如果不想因為這裡發生錯誤導致影響程式後續執行則需要使用try...except...
來捕獲和處理異常,如下所示
try:
100/0
except ZeroDivisionError as e:
print (f'異常物件資訊:{e}')
但是這是在明知會發生ZeroDivisionError的情況下做的處理,如果不知道會出現什麼型別的錯誤,並且希望無論發生什麼錯誤也不要影響程式的後續執行,則需要匹配全型別的異常,如下所示:
try:
100/0
except Exception as e:
print (f'異常物件資訊:{e}')
除此之外還可以去自定義錯誤型別:
# 自定義“小黑子”為一個異常物件
class XiaoHeiZi (Exception):
pass
# 定義一個接受文字的函式,如果接收到的文字是“jijiao”,則用關鍵字raise去拉起“小黑子”這個自定義異常
def iKUN(name):
if name == 'jijiao':
raise XiaoHeiZi()
try:
iKUN('jijiao')
except XiaoHeiZi:
print('你讓我拿什麼荔枝!!!')
traceback
當Python程式出現異常的時候通常會有一大串紅色的報錯,例如在執行下面這串程式碼
def level_3():
print ('進入 level_3')
a = [0]
b = a[1]
print ('離開 level_3')
def level_2():
print ('進入 level_2')
level_3()
print ('離開 level_2')
def level_1():
print ('進入 level_1')
level_2()
print ('離開 level_1')
level_1()
print('程式正常退出')
會得到如下報錯:
進入 level_1
進入 level_2
進入 level_3
Traceback (most recent call last):
File "C:\Users\chx\AppData\Local\Programs\PyCharm Community\plugins\python-ce\helpers\pydev\pydevd.py", line 1534, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\chx\AppData\Local\Programs\PyCharm Community\plugins\python-ce\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "D:\programming\python\python_basic\error.py", line 47, in <module>
level_1()
File "D:\programming\python\python_basic\error.py", line 43, in level_1
level_2()
File "D:\programming\python\python_basic\error.py", line 38, in level_2
level_3()
File "D:\programming\python\python_basic\error.py", line 33, in level_3
b = a[1]
~^^^
IndexError: list index out of range
這裡的報錯有兩個資訊,一個是錯誤發生的位置在level_3函式內33行的b = a[1]
處,第二個資訊就是說明了這行引起異常的程式碼, 是怎樣被 一層層的呼叫進來的,也就是函式呼叫棧的資訊。
而在使用了try-except處理異常後想看到該異常的呼叫棧資訊,則需要用到traceback模組,使用方法如下:
import traceback
def level_3():
print ('進入 level_3')
a = [0]
b = a[1]
print ('離開 level_3')
def level_2():
print ('進入 level_2')
level_3()
print ('離開 level_2')
def level_1():
print ('進入 level_1')
level_2()
print ('離開 level_1')
try:
level_1()
except :
print(f'未知異常:{traceback.format_exc()}')
print('程式正常退出')
筆記原始碼摘自白月黑羽教程