<style> .red { color: red; } .blue{ color: blue; } .green{ color: green; } </style> # 例外處理 ## 9-1 認識例外 ### 常見的錯誤類型: 1. **語法錯誤**(**syntax error**) 2. **執行期間錯誤**(**runtime error**) 3. **邏輯錯誤**(**logic error**) - 當Python程式發生錯誤時,系統會丟出一個例外(exception) - Traceback指的是此錯誤訊息是追朔到函式呼叫所發生的 ### 例外的類型 1. ImportError: 匯入module指令發生錯誤,可能是模型路徑或名稱有錯誤 2. IndexError: 索引運算子的範圍錯誤 3. MemoryError: 記憶體空間不足 4. NameError: 名稱尚未定義 ``` >>> def greet(name): >>> print("Hello, " + name + "!") >>> greet("Alice") >>> print(age) Traceback (most recent call last): File "example.py", line 5, in <module> print(age) NameError: name 'age' is not defined ``` 5. OverflowError: 溢位。指的是算術運算的結果太大,超過能夠表示的範圍 6. RuntimeError: 執行期間錯誤 7. SyntaxError: 語法錯誤 8. IndentationError: 縮排錯誤 9. SystemError: 直譯器(interpreter)發生內部錯誤 10. TypeError: 將運算或函式套用到型別錯誤的物件 ``` >>> def add_numbers(a, b): >>> return a + b >>> result = add_numbers(5, "10") >>> print(result) Traceback (most recent call last): File "example.py", line 4, in <module> result = add_numbers(5, "10") File "example.py", line 2, in add_numbers return a + b TypeError: unsupported operand type(s) for +: 'int' and 'str' ``` 11. ValueError: 內建運算或函式接收到型別正確但值錯誤的引述 ``` >>> def calculate_square_root(num): >>> if num < 0: >>> raise ValueError("Cannot calculate square root of a negative number.") >>> return num ** 0.5 >>> result = calculate_square_root(-9) >>> print(result) Traceback (most recent call last): File "example.py", line 6, in <module> result = calculate_square_root(-9) File "example.py", line 3, in calculate_square_root raise ValueError("Cannot calculate square root of a negative number.") ValueError: Cannot calculate square root of a negative number. ``` 12. ZeroDivisionError: 除以0的錯誤運算 13. ConnectError、ConnectAbortedError、ConnectRefusedError、ConnectionResetError: 連線錯誤、連線失敗、連線被拒絕、連線重設 14. FileExistsError: 企圖要建立已經存在的檔案或目錄,會導致檔案重複 15. FileNotFoundError: 要求的檔案或目錄不存在或找不到 16. TimeoutError: 系統函式逾時 ### 例外的處理 - 程式的執行是會經常遇到例外的發生,一旦遇到例外則整個程式會直接停止。上述這種情況其是不是我們想遇到的 - 比較理想的情況是,若遇到例外則去捕捉系統丟出的例外,然後根據系統丟出的例外叫使用者進行調整。此時整個程式仍然還在執行中 - 舉個例子: 若要求User輸入檔案位置,但User輸入錯誤。此時系統一定會丟出FileNotFoundError這個例外,而整個程式會終止。因此需要使用try...except來幫我們捕捉例外,然後使得程式在不停止的情況下,可以讓User重新輸入 ## 9-2 try...except ``` >>> while True: >>> try: >>> x = eval(input("請輸入被除數 x: ")) >>> y = eval(input("請輸入除數 y: ")) >>> z = x / y >>> except ZeroDivisionError: >>> print("除數不可以為0,請重新輸入!") # 這裡使用到指派變數給e1 # 透過e1的args屬性取得例外的訊息並且印出 >>> except Exception as e1: >>> print("發生錯誤:", e1.args) >>> print("請重新輸入!") >>> else: >>> print("沒有捕捉到例外! x 除以 y = ", z) >>> break >>> finally: >>> print("程式執行完畢,離開try...except區塊") # else, finally為選擇性statement,可以指定或省略 # finally statement可以用來清除錯誤或收尾 ``` - 若except後面不加任何的exceptionType,則預設型別為<span class='red'>BaseException,所有的例外都是繼承自這個型別</span> ### 自行丟出例外 ``` >>> raise NameError("Hello") ERROR! Traceback (most recent call last): File "<main.py>", line 1, in <module> NameError: Hello ``` ``` >>> try: >>> raise NameError("Hello") >>> except NameError: >>> print("捕捉到NameError!") 捕捉到NameError! ``` ### 例外處理的時機 - <span class='red'>當程式需要與外部交換資料時</span>: 存取檔案、透過網路連線執行某些動作、開啟資料庫等 - 透過加入例外處理,可以排除或顯示相關錯誤訊息來提醒使用者