Minghsin University of Science and Technology
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try a Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

1

Local AI

--

Uedu Code

--

明新科大 AQI 69 24°C PM2.5 26
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 17

例外處理

try/except/else/finally 與 raise
Interaction實作 25 minute(s)

Learning Objectives

  • 分辨語法錯誤(syntax error)與執行時的例外(exception)
  • Python 程式例外的流程:例外發生後程式往哪裡走
  • 用 try/except 攔截例外,包含多個 except 與 except ... as e
  • else、finally 的用法,以及用 raise 引發或重新引發例外

錯誤有兩種

寫程式一定會遇到錯誤。Python 最常見的錯誤分成兩種:

種類 什麼時候發生 例子
語法錯誤(syntax error,又稱剖析錯誤) 程式還沒開始執行,Python 讀程式碼時就發現寫錯了 while True print('Hello') 少了冒號
例外(exception) 語法正確,但執行到某一行時出了狀況 10 * (1/0) 除以 0、int('abc') 無法轉換
>>> while True print('Hello world')
  File "<stdin>", line 1
    while True print('Hello world')
               ^^^^^
SyntaxError: invalid syntax
>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

語法錯誤只能修改程式;例外則可以用 try/except 攔截,讓程式在出狀況時有替代方案,而不是直接中止。 Python 內建的例外類型很多,常見的有 ValueError、TypeError、ZeroDivisionError、IndexError、KeyError、NameError、FileNotFoundError。

沒有處理的例外:程式中止

迴圈依序計算 100 / v。播到 v 是 0 的那一圈,看看發生什麼事:紅色提示就是例外,之後的程式(包括最後一行)都不會執行。

try/except 的流程

try:
    可能出錯的程式
except 例外類型1:
    發生例外類型1 時執行
except 例外類型2:
    發生例外類型2 時執行
else:
    try 區塊完全沒出錯時執行
finally:
    不論有沒有出錯,最後一定執行
  1. 先執行 try 區塊。沒有出錯 → 略過所有 except。
  2. 某一行出錯 → try 裡剩下的程式全部略過,開始由上往下比對 except。
  3. 第一個符合的 except 執行(只會執行一個),然後繼續 try 敘述之後的程式。
  4. 都不符合 → 例外往外層的 try 送;外層都沒有處理,程式就中止並顯示錯誤訊息。

多個 except:第一個符合的才執行

輸入是 10,0。看執行箭頭在 r = n1 / n2 出錯後跳到哪一個 except,以及 print('r =', r) 有沒有執行。下方把輸入改成 10,4、10 4(少了逗號)、ten,2 各跑一次。

互動練習:例外會走哪一條路

點選不同的輸入,看程式依序經過哪些區塊。特別注意最後一種:沒有對應的 except 時,finally 仍然會先執行,然後程式才中止。

else 與 finally

輸入 8,2 沒有出錯,所以會執行 else,最後一定執行 finally。一個 except 可以用元組(tuple)同時攔截多種例外:except (ValueError, ZeroDivisionError):。把輸入改成 8,0 再跑一次,比較兩次的路線。

追蹤 try/except

1.

下面的程式會印出什麼?

try:
    print("A", end=" ")
    x = int("3")
    print("B", end=" ")
except ValueError:
    print("C", end=" ")
else:
    print("D", end=" ")
finally:
    print("E")
2.

下面的程式會印出什麼?

try:
    print("A", end=" ")
    x = int("three")
    print("B", end=" ")
except ValueError:
    print("C", end=" ")
else:
    print("D", end=" ")
finally:
    print("E")
3.

下面的程式會印出什麼?

try:
    nums = [1, 2, 3]
    print(nums[5])
except Exception:
    print("Exception")
except IndexError:
    print("IndexError")
第 1 次作答

except ... as e:取得錯誤資訊

例外可以帶一個物件,提供錯誤的相關資訊。except ValueError as e: 把這個例外物件指派給 e,print(e) 會印出錯誤訊息。看看 'abc' 與 None 分別引發哪一種例外。

except 子句的寫法

子句 說明
except: 攔截所有例外類型(容易把真正的錯誤藏起來,少用)
except 名稱: 只攔截特定例外
except 名稱 as e: 攔截特定例外,並取得例外物件
except (名稱1, 名稱2): 攔截多種例外
except (名稱1, 名稱2) as e: 攔截多種例外,並取得例外物件
else: 沒有例外發生時執行
finally: 不管有沒有發生例外,總是會執行

raise:自己引發例外

raise IndexError('Index out of range') 強制引發一個例外,括號裡的文字就是錯誤訊息。第一次輸入 7 超出範圍,被 except 接住後迴圈再問一次;第二次輸入 2 才成功並 break。

重新引發:讓呼叫者也能處理

在 except 裡只寫 raise(不加任何東西),會把同一個例外再丟出去。常見用法是先記錄或印出訊息,再交給呼叫者決定怎麼處理。看例外如何從 to_int 的框架傳回主程式。

想一想:raise 與 finally

1.

下面的程式會印出什麼?

try:
    age = -5
    if age < 0:
        raise ValueError("年齡不能是負數")
    print("OK")
except ValueError as e:
    print("錯誤:", e)
2.

下面的程式會印出什麼?

def f():
    try:
        return "try"
    finally:
        print("finally", end=" ")

print(f())
第 1 次作答

實作:安全的除法

串列 data 裡每個字串是「被除數,除數」。請用 try/except 完成迴圈:成功時印出商;除以 0 時印出 不能除以 0;不是整數時印出 請輸入整數。

你的輸出
預期輸出

重點精華回顧

  • 語法錯誤在執行前就被發現,只能改程式;例外是執行時發生的錯誤,可以攔截處理。
  • 例外發生後,try 裡剩下的程式被略過,由上往下比對 except,第一個符合的才執行;都不符合就往外層送,最外層也沒處理則程式中止。
  • except 名稱 as e 取得例外物件;except (名稱1, 名稱2) 一次攔截多種例外;較精確的例外要放前面。
  • else 只在沒有例外時執行;finally 不論如何都會執行(連 return 前也會先執行)。
  • raise 例外類型('訊息') 自己引發例外;在 except 裡單獨寫 raise 會把同一個例外重新引發給呼叫者。
這一課完成了!
Next lesson:檔案的讀寫
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。