iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0

第十三天:進階 Python:錯誤處理與例外管理

內容概述:

今天我們將探討 Python 中的錯誤處理機制。即便是最優秀的程式,在執行過程中仍可能遇到錯誤。學習如何有效處理這些錯誤,能夠讓程式更加健壯,並提供良好的用戶體驗。


一、什麼是錯誤與例外?

  1. 錯誤類型
    • 語法錯誤(Syntax Errors):當 Python 解析器無法理解程式時,會引發語法錯誤。

      • 例如,忘記了閉合括號或拼錯關鍵字。
      • print("Hello World"  # 少了右括號
        
    • 邏輯錯誤(Logical Errors):程式語法正確,但邏輯不正確,導致結果不符合預期。

    • 例外(Exceptions):例外是在程式執行過程中發生的錯誤,比如文件不存在、除以零等。

      • 例外可被程式捕捉並處理,避免程式崩潰。

二、常見的例外類型

  1. 常見例外類型

    • ZeroDivisionError: 嘗試將數字除以 0 時發生。
    • TypeError: 當操作或函數應用於不適當的類型時發生。
    • ValueError: 函數接收到正確類型,但值不正確時發生。
    • FileNotFoundError: 當程式嘗試打開不存在的文件時發生。
    # ZeroDivisionError 例子
    try:
        result = 10 / 0
    except ZeroDivisionError:
        print("Cannot divide by zero!")
    

三、使用 tryexcept 進行錯誤處理

  1. 基礎語法

    • 使用 try 來編寫可能會引發例外的程式碼,並使用 except 來處理這些例外。
    • 語法格式:
      try:
          # 可能發生例外的程式碼
      except SomeException:
          # 當例外發生時的處理
      
  2. 範例:處理使用者輸入錯誤

    try:
        user_input = int(input("Please enter a number: "))
    except ValueError:
        print("That's not a valid number!")
    

四、elsefinally 的使用

  1. else 子句

    • try 區塊中的程式碼沒有拋出任何例外時,else 區塊會執行:
      try:
          result = 10 / 2
      except ZeroDivisionError:
          print("Cannot divide by zero!")
      else:
          print(f"The result is {result}")
      
  2. finally 子句

    • finally 區塊中的程式碼無論是否發生例外都會執行,常用於釋放資源或清理操作。
      try:
          file = open("sample.txt", "r")
      except FileNotFoundError:
          print("File not found!")
      finally:
          file.close()  # 確保文件關閉
      

五、捕捉多個例外

  1. 捕捉多種類型的例外

    • 可以使用多個 except 來針對不同的例外類型進行處理:
      try:
          num = int(input("Enter a number: "))
          result = 100 / num
      except ValueError:
          print("That's not a number!")
      except ZeroDivisionError:
          print("You cannot divide by zero!")
      
  2. 捕捉所有例外

    • 使用 Exception 可以捕捉所有類型的例外,這樣可以避免漏掉任何潛在的錯誤:
      try:
          # 某些程式碼
      except Exception as e:
          print(f"An error occurred: {e}")
      

六、自定義例外

  1. 定義自己的例外類別

    • 可以創建自定義的例外類別來處理特殊情況。所有自定義例外都應繼承自 Exception 類別:
      class CustomError(Exception):
          pass
      
      def divide(a, b):
          if b == 0:
              raise CustomError("Cannot divide by zero")
          return a / b
      
      try:
          result = divide(10, 0)
      except CustomError as e:
          print(e)
      
  2. 使用自定義例外進行特殊處理

    • 自定義例外有助於處理特定情境下的錯誤,並提供更多上下文訊息。

七、實作範例

  1. 範例 1:計算器的錯誤處理

    • 我們可以使用錯誤處理來擴展簡單的計算器應用,防止用戶輸入不合法的數據或進行不合理的計算。

      def calculator():
          try:
              num1 = int(input("Enter first number: "))
              num2 = int(input("Enter second number: "))
              operation = input("Choose operation (+, -, *, /): ")
      
              if operation == "+":
                  result = num1 + num2
              elif operation == "-":
                  result = num1 - num2
              elif operation == "*":
                  result = num1 * num2
              elif operation == "/":
                  result = num1 / num2
              else:
                  raise ValueError("Invalid operation")
      
              print(f"The result is: {result}")
      
          except ValueError as ve:
              print(f"Input error: {ve}")
          except ZeroDivisionError:
              print("Cannot divide by zero")
          finally:
              print("Calculator session ended.")
      
      calculator()
      
  2. 範例 2:文件處理中的錯誤管理

    • 當處理文件時,錯誤處理非常重要。我們可以防止程序因為找不到文件或其他問題而崩潰。

      def read_file(file_path):
          try:
              with open(file_path, 'r') as file:
                  content = file.read()
                  print(content)
          except FileNotFoundError:
              print(f"File {file_path} not found.")
          except Exception as e:
              print(f"An error occurred: {e}")
      
      read_file("nonexistent_file.txt")
      

八、練習與實作

練習 1:捕捉錯誤
  • 寫一個簡單的數學計算器,要求使用者輸入兩個數字,並處理輸入的例外(如非數字輸入或除以零的情況)。
練習 2:文件讀取錯誤處理
  • 撰寫一個函數來讀取用戶指定的文件,如果文件不存在,提示用戶並捕捉 FileNotFoundError
練習 3:自定義例外處理
  • 創建一個自定義例外類別,並設計一個函數,在遇到某些特定情況(如非法輸入)時,拋出自定義例外。

解答

這些練習重點在於處理例外狀況,包括 Python 的內建例外和自定義例外處理。下面是各個練習的範例解答。


練習 1:捕捉錯誤

目標:寫一個簡單的數學計算器,要求使用者輸入兩個數字,並處理輸入的例外(如非數字輸入或除以零的情況)。

def calculator():
    try:
        num1 = float(input("請輸入第一個數字: "))
        num2 = float(input("請輸入第二個數字: "))
        operation = input("請選擇運算符號 (+, -, *, /): ")
        
        if operation == '+':
            result = num1 + num2
        elif operation == '-':
            result = num1 - num2
        elif operation == '*':
            result = num1 * num2
        elif operation == '/':
            result = num1 / num2
        else:
            print("無效的運算符號。")
            return

        print(f"計算結果: {result}")

    except ValueError:
        print("請輸入有效的數字。")
    except ZeroDivisionError:
        print("除數不能為零。")

# 測試程式
calculator()

解釋:

  • tryexcept:用來捕捉使用者輸入的錯誤,例如非數字輸入(捕捉 ValueError)和除以零(捕捉 ZeroDivisionError)。
  • float():將使用者輸入轉換為浮點數,若輸入非數字會引發 ValueError

練習 2:文件讀取錯誤處理

目標:撰寫一個函數來讀取用戶指定的文件,如果文件不存在,提示用戶並捕捉 FileNotFoundError

def read_file(filename):
    try:
        with open(filename, 'r', encoding='utf-8') as file:
            content = file.read()
            print("文件內容如下:")
            print(content)
    except FileNotFoundError:
        print(f"找不到文件: {filename}")
    except Exception as e:
        print(f"讀取文件時發生錯誤: {e}")

# 測試程式
filename = input("請輸入文件名稱: ")
read_file(filename)

解釋:

  • FileNotFoundError:當指定的文件不存在時會引發此錯誤,程式將捕捉並提示用戶。
  • open():打開文件,並使用 with 確保在操作結束後自動關閉文件。
  • Exception:捕捉任何其他潛在的錯誤。

練習 3:自定義例外處理

目標:創建一個自定義例外類別,並設計一個函數,在遇到某些特定情況(如非法輸入)時,拋出自定義例外。

# 自定義例外類別
class InvalidInputError(Exception):
    pass

def check_positive_number(number):
    if number < 0:
        raise InvalidInputError("輸入的數字不能為負數。")
    else:
        print(f"輸入的數字為: {number}")

# 測試程式
try:
    num = float(input("請輸入一個正數: "))
    check_positive_number(num)
except InvalidInputError as e:
    print(f"自定義錯誤: {e}")
except ValueError:
    print("請輸入有效的數字。")

解釋:

  • 自定義例外類別:透過創建一個繼承自 Exception 的類別 InvalidInputError 來定義自定義例外。
  • raise:當條件不滿足時,主動引發自定義的例外。
  • tryexcept:捕捉自定義例外 InvalidInputError,並顯示對應錯誤訊息。

這三個練習展示了例外處理在不同場景中的應用,包括捕捉內建例外、處理文件讀取錯誤,以及如何設計和使用自定義例外來處理特定的應用情境。


九、學習總結

錯誤處理是讓程式更加健壯與可靠的重要技術。通過合理使用 try-except 機制,我們可以確保程式在遇到問題時不會突然中斷,並且能夠提供清晰的錯誤訊息給用戶。隨著學習的深入,還可以使用自定義例外來更精細地控制錯誤處理邏輯。


下一堂課預告

第十四天:Python 進階:文件處理技巧與最佳實踐


上一篇
從 0 開始學!跟著 ChatGPT 學會 Python 物件導向程式設計(OOP)基礎
下一篇
從 0 開始學!跟著 ChatGPT 學會 Python 讀取&寫入文件
系列文
如果讓chatgpt參加iThome鐵人賽,他竟然寫出...!?31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言