1. 程式人生 > >Python 錯誤和異常

Python 錯誤和異常

簡述

程式中的錯誤一般被稱為 Bug,無可否認,這幾乎總是程式設計師的錯。。。

程式設計師的一生,始終伴隨著一件事 - 除錯(錯誤檢測、異常處理)。反反覆覆,最可怕的是:不僅自己的要改,別人的也要改。。。一萬頭草泥馬奔騰而過!

|

錯誤

程式錯誤,主要分為三類:

  • 語法錯誤
  • 邏輯錯誤
  • 執行時錯誤

語法錯誤

語法錯誤(也稱:解析錯誤):是指不遵循語言的語法結構引起的錯誤(程式無法正常編譯/執行)。

在編譯語言(例如:C++)中,語法錯誤只在編譯期出現,編譯器要求所有的語法都正確,才能正常編譯。不過對於直譯語言(例如:Python)來說,語法錯誤可能在執行期才會出現,而且不太容易區分語法錯誤及語義錯誤。

常見的 Python 語法錯誤有:

  • 遺漏了某些必要的符號(冒號、逗號或括號)
  • 關鍵字拼寫錯誤
  • 縮排不正確
  • 空語句塊(需要用 pass 語句)

例如,編寫這樣一個條件判斷語句:

>>> if n < 5
  File "<stdin>", line 1
    if n < 5
           ^
SyntaxError: invalid syntax

由於 if 語句中缺少一個冒號(:),不符合 Python 語法,因此程式無法正常執行。

邏輯錯誤

邏輯錯誤(也稱:語義錯誤):是指程式的執行結果與預期不符(程式可以正常執行,不會 Crash)。

與語法錯誤不同的是,邏輯錯誤從語法上來說是正確的,但會產生意外的輸出或結果,並不一定會被立即發現。邏輯錯誤的唯一表現就是錯誤的執行結果。

常見的邏輯錯誤有:

  • 運算子優先順序考慮不周
  • 變數名使用不正確
  • 語句塊縮排層次不對
  • 在布林表示式中出錯

例如,要計算兩個數的平均值:

>>> def average(a, b):
...     return a + b / 2  # 應為 (a + b) / 2
... 
>>> 

雖然程式能夠正常執行,但程式碼中缺少括號,由於運算子優先順序(先乘除,後加減)的緣故,運算結果並不正確。

執行時錯誤

執行時錯誤:是指程式可以執行,但是在執行過程中遇到錯誤,導致意外退出。

當程式由於執行時錯誤而停止時,通常會說程式崩潰了。在 Python 中,這種執行時錯誤被稱為異常。

Python 中的一些執行時錯誤:

  • 使用未定義的識別符號(NameError
  • 除數為 0(ZeroDivisionError
  • 開啟的檔案不存在(FileNotFoundError
  • 匯入的模組沒被找到(ImportError

例如,除數為 0:

>>> 5 / 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

每當出現這類執行時錯誤時,Python 就會建立一個異常物件。如果處理不當,會輸出一個跟蹤(Traceback)到那個錯誤,以及關於為什麼會出現錯誤的一些細節。

內建異常的層次結構

Python 中有許多內建的異常,當出現相應的錯誤時,就會引發這些異常。

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
           +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

注意: 當捕獲異常或者決定應該繼承哪個異常類時,這個層次關係非常有用。