Lesson 12: 例外與異常處理
def div(a, b): """ 回傳a/b""" return a/b num1 = div(100, 5) # 100除以5 num2 = div(5, 8) # 5除以8 num3 = div (6, 0) # 6除以0???
在模組的第7行出錯
函式div()第3行所造成
錯誤類型是: ZeroDivisionError
原因是 division by zero(除數為0)
錯誤類型: ValueError
原因是 輸入內容無法轉成整數
while True: n = int(input("請輸入分數: ")) if n==2: break if n==1: print('輸入指令1') # ... # 程式其他部分.... print('程式結束')
def div(a, b): """ 回傳a/b""" if b==0: # 程式自行排除不適用的參數值 print('除數不能為0') exit() # 程式結束 return a/b # 主程式 print(div(100, 5)) print(div(5, 8)) print(div (6, 0))
def div(a, b): """ 回傳a/b""" if b==0: # 程式自行排除不適用的參數值 print('除數不能為0') exit() # 程式結束 return a/b # 主程式 print(div(100, 5)) print(div(5, 8)) print(div (6, 0))
當除數參數b為0時,便不做除法
結束程式
通常不建議採用此方式處理
20.0
0.625
除數不能為0
執行結果
try:
指令 # 可能發生例外狀況的指令
except 異常物件: # 發生之異常狀況, 如ZeroDivisionError
異常狀況的處理程序 # 處理程序, 通常是印出異常訊息
def div(a, b): """ 回傳a/b""" try: return a/b except ZeroDivisionError: print('除數不得為0') # 主程式 print(div(100, 5)) print(div(5, 8)) print(div (6, 0))
def div(a, b): """ 回傳a/b""" try: return a/b except ZeroDivisionError: print('除數不得為0') # 主程式 print(div(100, 5)) print(div(5, 8)) print(div (6, 0))
20.0
0.625
除數不能為0
None
執行結果
try...except 語法
try...except 語法
while True: try: n = int(input("請輸入分數: ")) break except ValueError: print("輸入的不是整數, 請重新輸入") print(f"讚!你輸入的整數是{n}")
try...except 語法
def int_input(prompt): while True: try: score = int(input(prompt)) # 若int()成功,執行下一行 return score except ValueError as e: # int()出現錯誤 print("輸入的不是整數!請重新輸入") myScore = int_input('輸入成績:') if myScore >= 60: print(f'{myScore}分:及格') else: print('f{myScore}分:不及格')
try...except 語法
def read_file(fn, encoding='utf-8'): try: with open(fn, encoding=encoding) as fobj: data = fobj.readlines() fobj.close() return data except FileNotFoundError: print(f'檔案{fn}找不到') exit(0) # 主程式 fn = 'test.txt' data = read_file(fn) for line_num in range(len(data)): print(f'{line_num+1:>03}:{data[line_num].strip()}')
try: print(x) except NameError: print("變數 x 未定義")
# 主程式開始 fn = 'test.py' try: with open(fn, encoding='utf-8') as fobj: data = fobj.read() except FileNotFoundError: print('檔案 %s 無法開啟' % fn)
變數未定義
檔案無法開啟
try: print(x) except NameError: print("變數 x 未定義") except: print("發生其他錯誤")
try: answer = x / y except NameError: print('變數未定義') except ZeroDivisionError: print('除法分母不得為0')
變數未定義 及 其他錯誤
變數未定義 及 除法錯誤
fn = 'test3.py' try: with open(fn, encoding='utf-8') as fobj: data = fobj.read() except FileNotFoundError: print('檔案 %s 無法開啟' % fn)
fn = 'test3.py' try: with open(fn, encoding='utf-8') as fobj: data = fobj.read() except FileNotFoundError as error_msg: print(error_msg)
fn = 'test3.py' try: with open(fn, encoding='utf-8') as fobj: data = fobj.read() except FileNotFoundError as error_msg: print(error_msg)
檔案 test.py 無法開啟
執行結果
[Errno 2] No such file or directory: 'test3.py'
執行結果
try:
指令 # 可能發生例外狀況的指令
except 異常物件: # 發生之異常狀況, 如ZeroDivisionError
異常狀況的處理程序 # 處理程序, 通常是印出異常訊息
else:
正常的處理程序
try...except else: 指令正常時,執行else區塊
def div(a, b): """ 回傳a/b""" try: return a/b except ZeroDivisionError: print('除數不得為0') # 主程式 print(div(100, 5)) print(div(5, 8)) print(div (6, 0))
def div(a, b): """ 回傳a/b""" try: return a/b except ZeroDivisionError: print('除數不得為0') # 主程式 print(div(100, 5)) print(div(5, 8)) print(div (6, 0))
def div(a, b): """ 回傳a/b""" try: return a/b except ZeroDivisionError: print('除數不得為0') # 主程式 print(div(100, 5)) print(div(5, 8)) print(div (6, 0))
20.0
0.625
除數不能為0
None
執行結果
# 主程式開始 fn = 'test.py' try: with open(fn, encoding='utf-8') as fobj: data = fobj.read() except FileNotFoundError: print('檔案 %s 無法開啟' % fn) else: print(data)
# 主程式開始 fn = 'test.py' try: with open(fn, encoding='utf-8') as fobj: data = fobj.read() except FileNotFoundError: print('檔案 %s 無法開啟' % fn) else: print(data)
檔案 test.py 無法開啟
執行結果
...
area = 3.14 * r**2 # 指定運算子
print('面積是 %8.2f' % area)
...
執行結果
# 函式openFile def openFile(fn, code='cp950'): # 未處理異常狀況 with open(fn, encoding=code) as fobj: data = fobj.read() return data # 主程式開始 fn = 'test.py' try: data = openFile(fn,'utf-8') #也可由呼叫函式端處理 except FileNotFoundError: print('檔案 %s 無法開啟' % fn) else: print(data)
# 函式openFile def openFile(fn, code='cp950'): # 未處理異常狀況 with open(fn, encoding=code) as fobj: data = fobj.read() return data # 主程式開始 fn = 'test.py' try: data = openFile(fn,'utf-8') #也可由呼叫函式端處理 except FileNotFoundError: print('檔案 %s 無法開啟' % fn) else: print(data)
檔案 test.py 無法開啟
執行結果
...
area = 3.14 * r**2 # 指定運算子
print('面積是 %8.2f' % area)
...
執行結果
異常物件類型 | |
---|---|
ZeroDivisionError | 除數為0的錯誤 |
FileNotFoundError | 找不到所指定的檔案 |
Exception | 通用型,所有錯誤皆可使用 |
IndexError | 索引值超出範圍 |
IOError | 輸出或輸入發生的錯誤(例如: 檔案找不到) |
SyntaxError | 語法錯誤 |
TypeError | 資料型別錯誤 |
Exception包含所有異常物件
IOError包含FileNotFoundError
# 主程式開始 fn = 'test.txt' try: with open(fn) as fobj: data = fobj.read() except FileNotFoundError: print('檔案 %s 無法開啟' % fn) else: print(data)
# 主程式開始 fn = 'test.txt' try: with open(fn) as fobj: data = fobj.read() except FileNotFoundError: print('檔案 %s 無法開啟' % fn) else: print(data)
# 主程式開始 fn = 'test.txt' try: with open(fn) as fobj: data = fobj.read() except Exception: print('發生錯誤') else: print(data)
# 主程式開始 fn = 'test.txt' try: with open(fn) as fobj: data = fobj.read() except IOError: print('發生IO錯誤') else: print(data)
不保證是FileNotFoundError!
不保證是IOError!
try:
指令 # 可能發生例外狀況的指令
except 異常物件: # 發生之異常狀況, 如ZeroDivisionError
異常狀況的處理程序 # 處理程序, 通常是印出異常訊息
else:
正常的處理程序
finally:
必須執行的區塊 # 異常 or 正常程序處理後,都要執行此處
try: fobj = open('test.txt') # 假設檔案存在 data = fobj.read() except IOError as msg: print(msg) else: print(data) finally: fobj.close() # 不管有無發生讀寫異常, 檔案都須關閉