# 內建的例外

在 Python 中，所有例外必須是從 `BaseException` 衍生的類別的實例。在陳述式 `try` 搭配 `except` 子句裡提到一個特定的類別時，那個子句也會處理任何從該類別衍生的例外類別（但不會處理該類別衍生自的例外類別）。兩個不是由子類別關係關聯起來的例外類別永遠不相等，就算它們有相同的名稱也是如此。

此章節裡列出的內建例外可以從直譯器或內建函式產生。除了特別提到的地方之外，它們會有一個關聯值表示錯誤發生的詳細原因。這可能是一個字串，或者是一些資訊項目組成的元組（例如一個錯誤代碼及一個解釋該代碼的字串）。這個關聯值通常當作引數傳遞給例外類別的建構函式。

使用者的程式碼可以引發內建例外。這可以用來測試例外處理器或者用來回報一個錯誤條件，就像直譯器會引發相同例外的情況；但需要注意的是沒有任何方式可以避免使用者的程式碼引發不適當的錯誤。

可以從內建的例外類別定義新的例外子類別；程式設計師被鼓勵從 `Exception` 類別或其子類別衍生新的例外，而不是從 `BaseException` 來衍生。更多關於定義例外的資訊可以在 Python 教學中的使用者自定的例外裡取得。

## 例外的情境

三個例外物件上的屬性提供關於引發此例外的情境的資訊：

BaseException.__context__
BaseException.__cause__
BaseException.__suppress_context__

  當引發一個新的例外而同時有另一個例外已經正在被處理時，這個新例外的 `__context__` 屬性會自動被設成那個已處理的例外。當使用 `except` 或 `finally` 子句或 `with` 陳述式的時候例外會被處理。

  這個隱含的例外情境可以透過使用 `from` 搭配 `raise` 來補充明確的原因：

      raise new_exc from original_exc

  在 `from` 後面的運算式必須是一個例外或 `None`。它將會被設定成所引發例外的 `__cause__`。設定 `__cause__` 也隱含地設定 `__suppress_context__` 屬性為 `True`，因此使用 `raise new_exc from None` 實際上會以新的例外取代舊的例外以利於顯示（例如轉換 `KeyError` 為 `AttributeError`），同時保持舊的例外可以透過 `__context__` 取得以方便 debug 的時候檢查。

  預設的回溯 (traceback) 顯示程式碼會顯示這些連鎖的例外 (chained exception) 加上例外本身的回溯。當存在的時候，在 `__cause__` 中明確地連鎖的例外總是會被顯示。而在 `__context__` 中隱含地連鎖的例外只有當 `__cause__` 是 `None` 且 `__suppress_context__` 是 false 時才會顯示。

  在任一種情況下，例外本身總是會顯示在任何連鎖例外的後面，因此回溯的最後一列總是顯示最後一個被引發的例外。

## 繼承自內建的例外

使用者的程式碼可以建立繼承自例外型別的子類別。建議一次只繼承一種例外型別以避免在基底類別之間如何處理 `args` 屬性的任何可能衝突，以及可能的記憶體佈局 (memory layout) 不相容。

為了效率，大部分的內建例外使用 C 來實作，參考 Objects/exceptions.c。一些例外有客製化的記憶體佈局，使其不可能建立一個繼承多種例外型別的子類別。型別的記憶體佈局是實作細節且可能會在不同 Python 版本間改變，造成未來新的衝突。因此，總之建議避免繼承多種例外型別。

## 基底類別 (base classes)

以下的例外大部分被用在當作其他例外的基底類別。

exception BaseException

  所有內建例外的基底類別。這不是為了讓使用者定義的類別直接繼承（可以使用 `Exception`）。如果在這個類別的實例上呼叫 `str()`，會回傳實例的引數的表示，或者沒有引數的時候會回傳空字串。

  args

    提供給該例外建構函式的引數元組。一些內建的例外（像是 `OSError`）預期接受特定數量的引數並賦予該元組的每一個元素一個特別的意義，其他例外則通常用一個提供錯誤訊息的單一字串來呼叫。

  with_traceback(tb)

    此方法設定 tb 為該例外的新的回溯並回傳該例外物件。在 PEP 3134 的例外連鎖功能變得可用之前，此方法曾被更普遍使用。下面的範例顯示我們如何將 `SomeException` 的實例轉換為 `OtherException` 的實例同時保留回溯。一旦被引發，目前的 frame 會被加進 `OtherException` 的回溯，就像原來 `SomeException` 的回溯會發生的一樣，我們允許它被傳遞給呼叫者：

        try:
            ...
        except SomeException:
            tb = sys.exception().__traceback__
            raise OtherException(...).with_traceback(tb)

  __traceback__

    可寫入的欄位，儲存關聯到該例外的回溯物件。也可以參考 raise 陳述式。

  add_note(note)

    新增字串 `note` 到例外的備註，在標準的回溯裡，備註出現在例外字串的後面。如果 `note` 不是字串則引發 `TypeError`。

    在 3.11 版被加入.

  __notes__

    該例外的備註串列，使用 `add_note()` 來新增。此屬性在 `add_note()` 被呼叫的時候建立。

    在 3.11 版被加入.

exception Exception

  所有內建、非系統退出 (non-system-exiting) 的例外都衍生自此類別。所有使用者定義的例外應該也要衍生自此類別。

exception ArithmeticError

  各種運算錯誤所引發的那些內建例外：`OverflowError`、`ZeroDivisionError`、`FloatingPointError` 的基底類別。

exception BufferError

  當緩衝 (buffer) 相關的操作無法被執行時會引發此例外。

exception LookupError

  當使用在對映或序列上的鍵或索引是無效的時候所引發的例外：`IndexError`、`KeyError` 的基底類別。這可以被 `codecs.lookup()` 直接引發。

## 實體例外

以下的例外是通常會被引發的例外。

exception AssertionError

  當 `assert` 陳述式失敗的時候被引發。

exception AttributeError

  當屬性參照（參考 Attribute references）或賦值失敗的時候被引發。（當物件根本不支援屬性參照或屬性賦值的時候，`TypeError` 會被引發。）

  可選的僅限關鍵字引數 name 和 obj 會設定對應的屬性：

  name

    嘗試被存取的屬性名稱。

  obj

    存取指定屬性的物件。

  在 3.10 版的變更: 新增 `name` 與 `obj` 屬性。

exception EOFError

  當 `input()` 函式在沒有讀到任何資料而到達檔案結尾 (end-of-file, EOF) 條件的時候被引發。（注意：`io.IOBase.read()` 和 `io.IOBase.readline()` 方法當達到 EOF 時會回傳空字串。）

exception FloatingPointError

  目前沒有被使用。

exception GeneratorExit

  當 generator 或 coroutine 被關閉的時候被引發；參考 `generator.close()` 和 `coroutine.close()`。此例外直接繼承自 `BaseException` 而不是 `Exception`，因為技術上來說這不是一個錯誤。

exception ImportError

  當 `import` 陳述式嘗試載入模組遇到問題的時候會被引發。當 `from ... import` 裡的 "from list" 包含找不到的名稱時也會被引發。

  可選的僅限關鍵字引數 name 和 path 設定對應的屬性：

  name

    嘗試引入 (import) 的模組名稱。

  path

    觸發此例外的任何檔案的路徑。

  在 3.3 版的變更: 新增 `name` 與 `path` 屬性。

exception ModuleNotFoundError

  `ImportError` 的子類別，當模組不能被定位的時候會被 `import` 所引發。當在 `sys.modules` 裡找到 `None` 時也會被引發。

  在 3.6 版被加入.

exception IndexError

  當序列的索引超出範圍的時候會被引發。（切片索引 (slice indices) 會默默地被截短使其能落在允許的範圍內；如果索引不是整數，`TypeError` 會被引發。）

exception KeyError

  當對映（字典）的鍵無法在已存在的鍵的集合中被找到時會被引發。

exception KeyboardInterrupt

  當使用者輸入中斷鍵 (interrupt key)（一般來說是 `Control`-`C` 或 `Delete`）時會被引發。在執行過程中，會定期檢查是否產生中斷。此例外繼承自 `BaseException` 以防止意外地被捕捉 `Exception` 的程式碼所捕捉，而因此讓直譯器無法結束。

  備註

  捕捉 `KeyboardInterrupt` 需要特殊的考量。因為它可以在無法預期的時間點被引發，可能在某些情況下讓正在跑的程式處在一個不一致的狀態。一般來說最好讓 `KeyboardInterrupt` 越快結束程式越好，或者完全避免引發它。（參考 訊號處理程式與例外的說明。）

exception MemoryError

  當一個操作用光了記憶體但情況還可能被修復 (rescued)（透過刪除一些物件）的時候被引發。關聯值是一個字串，表示什麼類型的（內部）操作用光了記憶體。需注意的是因為底層的記憶體管理架構（C 的 `malloc()` 函式），直譯器可能無法總是完整地從該情況中修復；僅管如此，它還是引發例外以讓堆疊回溯可以被印出，以防原因出在失控的程式。

exception NameError

  當找不到本地或全域的名稱時會被引發。這只應用在不合格的名稱 (unqualified name) 上。關聯值是一個錯誤訊息，包含那個無法被找到的名稱。

  可選的僅限關鍵字引數 name 設定對應的屬性：

  name

    嘗試被存取的變數名稱。

  在 3.10 版的變更: 新增 `name` 屬性。

exception NotImplementedError

  此例外衍生自 `RuntimeError`。在使用者定義的基礎類別裡，當抽象方法要求衍生類別覆寫該方法時應該要引發此例外，或者當類別正在開發中，可用此例外表示還需要加入真正的實作。

  備註

  此例外不應該用來表示根本沒有要支援的運算子或方法 ── 在這個情況下可以讓該運算子或方法保持未定義，或者如果是子類別的話將其設成 `None`。

  警示

  `NotImplementedError` 和 `NotImplemented` 並不是可互換的。這個例外只能用在上面描述的情況；參考 `NotImplemented` 裡關於內建常數正確使用方法的細節。

exception OSError([arg])
exception OSError(errno, strerror[, filename[, winerror[, filename2]]])

  當系統函式回傳系統相關錯誤，包含像"找不到檔案"或"硬碟已滿"的 I/O 失敗會引發此例外（而非不合法的引數或其他次要的錯誤）。

  建構函式的第二種形式會設定以下描述的相對應屬性。如果沒有給定則屬性預設為 `None`。為了向後相容，如果傳入三個引數，`args` 屬性只會是包含建構函式前兩個引數的雙元素元組。

  如同下面的作業系統例外所描述，實際上建構函式通常回傳 `OSError` 的子類別。會依據最後 `errno` 的值決定特定子類別。這個行為只發生在直接建構 `OSError` 或透過別名，且產生子類別的時候不會被繼承。

  errno

    從 C 變數 `errno` 而來的數值錯誤代碼。

  winerror

    在 Windows 下，這會提供你原生的 Windows 錯誤代碼。而 `errno` 屬性是一個該原生錯誤代碼對於 POSIX 來說的近似翻譯。

    在 Windows 下，如果建構函式引數 winerror 是整數，則 `errno` 屬性會根據該 Windows 錯誤代碼來決定，且 errno 引數會被忽略。在其他平台上，winerror 引數會被忽略，而 `winerror` 屬性會不存在。

  strerror

    作業系統提供的對應錯誤訊息。在 POSIX 下會使用 C 函式 `perror()` 做格式化，而在 Windows 下會使用 `FormatMessage()`。

  filename
  filename2

    對於包含檔案系統路徑的例外（像是 `open()` 或 `os.unlink()`），`filename` 是傳入函式的檔案名稱。對於包含兩個檔案系統路徑的函式（像是 `os.rename()`），`filename2` 對應到傳入函式的第二個檔案名稱。

  在 3.3 版的變更: `EnvironmentError`、`IOError`、`WindowsError`、`socket.error`、`select.error` 及 `mmap.error` 已合併進 `OSError`，而建構函式可能會回傳子類別。

  在 3.4 版的變更: `filename` 屬性現在是傳入函式的原始檔名，而不是從檔案系統編碼和錯誤處理函式編碼或解碼過的名稱。並且新增 filename2 建構函式引數與屬性。

exception OverflowError

  當運算操作的結果太大而無法表示的時候會引發此例外。這不會發生在整數上（會改成引發 `MemoryError` 而不是放棄）。然而，因為一些歷史因素，OverflowError 有時候會因為整數在要求範圍之外而引發。因為在 C 裡面缺乏浮點數例外處理的標準化，大部分的浮點數運算都沒有被檢查。

exception PythonFinalizationError

  此例外衍生自 `RuntimeError`。當一個操作在直譯器關閉（也稱作 Python 最終化 (Python finalization））期間被阻塞會引發此例外。

  在 Python 最終化期間，能夠以 `PythonFinalizationError` 被阻塞的操作範例：

  - 建立新的 Python 執行緒。

  - `os.fork()`。

  也可以參閱 `sys.is_finalizing()` 函式。

  在 3.13 版被加入: 在之前，會引發一般的 `RuntimeError`。

exception RecursionError

  此例外衍生自 `RuntimeError`。當直譯器偵測到超過最大的遞迴深度（參考 `sys.getrecursionlimit()`）時會引發此例外。

  在 3.5 版被加入: 在之前，會引發一般的 `RuntimeError`。

exception ReferenceError

  當一個被 `weakref.proxy()` 函式建立的弱參照代理 (weak reference proxy) 被用來存取已經被垃圾回收 (garbage collected) 的參照物屬性時會引發此例外。更多關於弱參照的資訊參考 `weakref` 模組。

exception RuntimeError

  當偵測到一個不屬於任何其他種類的錯誤時會引發此例外。關聯值是一個表示確切什麼地方出錯的字串。

exception StopIteration

  會被內建函式 `next()` 及 iterator 的 `__next__()` 方法引發，用來表示疊代器沒有更多項目可以產生。

  value

    此例外物件有單一屬性 `value`，當建構此例外時會以引數給定，預設為 `None`。

  當 generator 或 coroutine 函式回傳時，新的 `StopIteration` 實例會被引發，而該函式的回傳值會被用來當作此例外建構函式的 `value` 參數。

  如果產生器程式直接或間接引發 `StopIteration`，則其會被轉換成 `RuntimeError`（保留 `StopIteration` 作為新例外的成因）。

  在 3.3 版的變更: 新增 `value` 屬性且產生器函式可以用它來回傳值。

  在 3.5 版的變更: 透過 `from __future__ import generator_stop` 引入 RuntimeError 的轉換，參考 PEP 479。

  在 3.7 版的變更: 預設對所有程式啟用 PEP 479：在產生器引發的 `StopIteration` 錯誤會轉換成 `RuntimeError`。

exception StopAsyncIteration

  此例外必須被 asynchronous iterator 物件的 `__anext__()` 方法引發來停止疊代。

  在 3.5 版被加入.

exception SyntaxError(message, details)

  當剖析器遇到語法錯誤時會引發此例外。這可能發生在 `import` 陳述式、在呼叫內建函式 `compile()`、`exec()` 或 `eval()` 的時候，或者在讀取初始腳本或標準輸入（也包含互動式）的時候。

  例外實例的 `str()` 只回傳錯誤訊息。Details 是個元組，其成員也能夠以分開的屬性取得。

  filename

    發生語法錯誤所在的檔案名稱。

  lineno

    發生錯誤所在檔案的列號。這是以 1 開始的索引：檔案第一列的 `lineno` 是 1。

  offset

    發生錯誤所在該列的欄號 (column)。這是以 1 開始的索引：該列第一個字元的 `offset` 是 1。

  text

    涉及該錯誤的原始程式碼文字。

  end_lineno

    發生錯誤所在檔案的結束列號。這是以 1 開始的索引：檔案第一列的 `lineno` 是 1。

  end_offset

    發生錯誤所在該結束列的欄號。這是以 1 開始的索引：該列第一個字元的 `offset` 是 1。

  對於發生在 f-string 欄位的錯誤，訊息會以 "f-string: " 為前綴，而偏移量 (offset) 是從替代表達式建構的文字的偏移量。例如編譯 f'Bad {a b} field' 會得到這個 args 屬性：('f-string: ...', ('', 1, 2, '(a b)n', 1, 5))。

  在 3.10 版的變更: 新增 `end_lineno` 與 `end_offset` 屬性。

exception IndentationError

  與不正確的縮排有關的語法錯誤的基礎類別。這是 `SyntaxError` 的子類別。

exception TabError

  當縮排包含製表符號 (tab) 和空白的不一致用法時會引發此例外。這是 `IndentationError` 的子類別。

exception SystemError

  當直譯器找到一個內部錯誤，但該情況看起來沒有嚴重到要讓它放棄所有的希望時會引發此例外。關聯值是一個表示什麼地方出錯的字串（以低階的方式表達）。在 CPython 中，這可能是因為錯誤地使用 Python 的 C API，例如回傳一個 `NULL` 值而沒有設定例外。

  如果你確定這個例外不是你的或者所用套件的錯，你應該向你的 Python 直譯器作者或維護者回報此錯誤。務必要回報該 Python 直譯器的版本（`sys.version`；這也會在互動式 Python 會話的開頭被印出）、確切的錯誤訊息（該例外的關聯值）及如果可能的話，觸發此錯誤的程式來源。

exception SystemExit

  此例外會被 `sys.exit()` 函式引發。它繼承自 `BaseException` 而不是 `Exception` 因此不會被捕捉 `Exception` 的程式意外地捕捉。這允許例外可以正確地向上傳遞並導致直譯器結束。當它未被處理時，Python 直譯器會結束；不會印出堆疊回溯。建構函式接受跟傳入 `sys.exit()` 一樣的可選引數。如果該值是整數，它會指定系統的結束狀態（傳入 C 的 `exit()` 函式）；如果它是 `None`，結束狀態會是 0；如果它是其他型別（例如字串），則物件的值會被印出而結束狀態是 1。

  對 `sys.exit()` 的呼叫會轉譯成例外讓負責清理的處理函式（`try` 陳述式的 `finally` 子句）可以被執行，且讓除錯器可以在不冒著失去控制的風險下執行腳本。如果在絕對有必要立即結束的情況（例如在子行程呼叫完 `os.fork()` 之後 ）可以使用 `os._exit()` 函式。

  code

    傳入建構函式的結束狀態或錯誤訊息。（預設是 `None`。 ）

exception TypeError

  當一個操作或函式被用在不適合的型別的物件時會引發此例外。關聯值是一個字串，提供關於不相符型別的細節。

  此例外可能被使用者程式碼引發，以表示並不支援物件上所嘗試的操作，且本來就無意這樣做。如果一個物件有意要支援某個給定的操作但尚未提供實作，該引發的正確例外是 `NotImplementedError`。

  傳入錯誤型別的引數（例如當預期傳入 `int` 卻傳入 `list`）應該要導致 `TypeError`，但傳入帶有錯誤值的引數（例如超出預期範圍的數值）應該要導致 `ValueError`。

exception UnboundLocalError

  當在函式或方法裡引用某個區域變數，但該變數尚未被繫結到任何值的時候會引發此例外。這是 `NameError` 的子類別。

exception UnicodeError

  當 Unicode 相關的編碼或解碼錯誤發生時會引發此例外。這是 `ValueError` 的子類別。

  `UnicodeError` 有屬性描述編碼或解碼錯誤。例如 `err.object[err.start:err.end]` 會提供讓編解碼器失敗的具體無效輸入。

  encoding

    引發錯誤的編碼名稱。

  reason

    描述特定編解碼器錯誤的字串。

  object

    編解碼器嘗試編碼或解碼的物件。

  start

    在 `object` 中無效資料的開始索引。

  end

    在 `object` 中最後的無效資料後的索引。

exception UnicodeEncodeError

  在編碼當中發生 Unicode 相關錯誤時會引發此例外。這是 `UnicodeError` 的子類別。

exception UnicodeDecodeError

  在解碼當中發生 Unicode 相關錯誤時會引發此例外。這是 `UnicodeError` 的子類別。

exception UnicodeTranslateError

  在轉譯當中發生 Unicode 相關錯誤時會引發此例外。這是 `UnicodeError` 的子類別。

exception ValueError

  當一個操作或函式收到引數是正確型別但是不適合的值，且該情況無法被更精確的例外例如 `IndexError` 所描述時會引發此例外。

exception ZeroDivisionError

  當除法或模數運算 (modulo operation) 的第二個引數是 0 的時候會引發此例外。關聯值是一個字串，表示運算元及運算的類型。

以下例外是為了相容於之前版本而保留；從 Python 3.3 開始，它們是 `OSError` 的別名。

exception EnvironmentError

exception IOError

exception WindowsError

  僅限於在 Windows 中使用。

### 作業系統例外

以下的例外是 `OSError` 的子類別，它們根據系統錯誤代碼來引發。

exception BlockingIOError

  當設置為非阻塞操作的物件（例如 socket）上的操作將要阻塞時會引發此例外。對應到 `errno` `EAGAIN`、`EALREADY`、`EWOULDBLOCK` 及 `EINPROGRESS`。

  除了 `OSError` 的那些屬性之外，`BlockingIOError` 有多一個屬性：

  characters_written

    An integer containing the number of bytes written to the stream before it blocked. This attribute is available when using the buffered I/O classes from the `io` module.

exception ChildProcessError

  當子行程上的操作失敗時會引發此例外。對應到 `errno` `ECHILD`。

exception ConnectionError

  連線相關問題的基礎類別。

  子類別有 `BrokenPipeError`、`ConnectionAbortedError`、`ConnectionRefusedError` 及 `ConnectionResetError`。

exception BrokenPipeError

  `ConnectionError` 的子類別，當嘗試寫入管道 (pipe) 同時另一端已經被關閉時會引發此例外，或者當嘗試寫入已關閉寫入的 socket 時也會引發。對應到 `errno` `EPIPE` 及 `ESHUTDOWN`。

exception ConnectionAbortedError

  `ConnectionError` 的子類別。當一個連線的嘗試被對等端點 (peer) 中斷時會引發此例外。對應到 `errno` `ECONNABORTED`。

exception ConnectionRefusedError

  `ConnectionError` 的子類別。當一個連線的嘗試被對等端點拒絕時會引發此例外。對應到 `errno` `ECONNREFUSED`。

exception ConnectionResetError

  `ConnectionError` 的子類別。當一個連線被對等端點重置時會引發此例外。對應到 `errno` `ECONNRESET`。

exception FileExistsError

  當嘗試建立已存在的檔案或目錄時會引發此例外。對應到 `errno` `EEXIST`。

exception FileNotFoundError

  當請求不存在的檔案或目錄時會引發此例外。對應到 `errno` `ENOENT`。

exception InterruptedError

  當系統呼叫被傳入的信號中斷時會引發此例外。對應到 `errno` `EINTR`。

  在 3.5 版的變更: 現在當 syscall 被信號中斷時 Python 會重試系統呼叫而不會引發 `InterruptedError`，除非信號處理器引發例外（理由可參考 PEP 475）。

exception IsADirectoryError

  當在目錄上請求檔案操作（例如 `os.remove()`）時會引發此例外。對應到 `errno` `EISDIR`。

exception NotADirectoryError

  當在某個不是目錄的東西上請求目錄操作（例如 `os.listdir()`）時會引發此例外。在大多數的 POSIX 平台上，如果嘗試操作開啟或遍歷一個當作目錄的非目錄檔案也會引發此例外。對應到 `errno` `ENOTDIR`。

exception PermissionError

  當嘗試執行一個沒有合乎存取權限的操作時會引發此例外 — 例如檔案系統權限。對應到 `errno` `EACCES`、`EPERM` 及 `ENOTCAPABLE`。

  在 3.11.1 版的變更: WASI 的 `ENOTCAPABLE` 現在對應到 `PermissionError`。

exception ProcessLookupError

  當給定的行程不存在時會引發此例外。對應到 `errno` `ESRCH`。

exception TimeoutError

  當系統函式在系統層級超時會引發此例外。對應到 `errno` `ETIMEDOUT`。

在 3.3 版被加入: 加入以上所有的 `OSError` 子類別。

也參考

PEP 3151 — 改寫作業系統與 IO 例外階層

## 警告

以下的例外是當作警告的種類使用；更多細節參考 警告類別 文件。

exception Warning

  警告種類的基礎類別。

exception UserWarning

  使用者程式碼產生的警告的基礎類別。

exception DeprecationWarning

  關於已棄用功能的警告的基礎類別，且當那些警告是針對其他 Python 開發者。

  會被預設的警告過濾器忽略，在 `__main__` 模組裡除外 (PEP 565)。啟用 Python 開發模式會顯示此警告。

  棄用原則描述在 PEP 387 裡。

exception PendingDeprecationWarning

  關於過時且預期未來要被棄用，但目前尚未被棄用的功能的警告的基礎類別。

  因為發出關於可能即將被棄用的警告是不尋常的，此類別很少被使用，而對已經被棄用的情況會優先使用 `DeprecationWarning`。

  會被預設的警告過濾器忽略。啟用 Python 開發模式會顯示此警告。

  棄用原則描述在 PEP 387 裡。

exception SyntaxWarning

  關於可疑語法的警告的基礎類別。

  This warning is typically emitted when compiling Python source code, and usually won't be reported when running already compiled code.

exception RuntimeWarning

  關於可疑執行環境行為的警告的基礎類別。

exception FutureWarning

  關於已棄用功能的警告的基礎類別，且當那些警告是針對以 Python 寫的應用程式的終端使用者。

exception ImportWarning

  關於在模組引入的可能錯誤的警告的基礎類別。

  會被預設的警告過濾器忽略。啟用 Python 開發模式會顯示此警告。

exception UnicodeWarning

  Unicode 相關警告的基礎類別。

exception EncodingWarning

  編碼相關警告的基礎類別。

  細節參考選擇性加入的編碼警告。

  在 3.10 版被加入.

exception BytesWarning

  `bytes` 及 `bytearray` 相關警告的基礎類別。

exception ResourceWarning

  資源用法相關警告的基礎類別。

  會被預設的警告過濾器忽略。啟用 Python 開發模式會顯示此警告。

  在 3.2 版被加入.

## 例外群組

當需要引發多個不相關例外時會使用下列的類別。它們是例外階層的一部分所以可以像所有其他例外一樣使用 `except` 來處理。此外，它們會以包含的例外型別為基礎來比對其子群組而被 `except*` 辨認出來。

exception ExceptionGroup(msg, excs)

exception BaseExceptionGroup(msg, excs)

  這兩個例外型別都將例外包裝在序列 `excs` 中。`msg` 參數必須是字串。這兩個類別的差異是 `BaseExceptionGroup` 擴充了 `BaseException` 且可以包裝任何例外，而 `ExceptionGroup` 擴充了 `Exception` 且只能包裝 `Exception` 的子類別。這個設計使得 `except Exception` 可以捕捉 `ExceptionGroup` 但不能捕捉 `BaseExceptionGroup`。

  如果所有包含的例外都是 `Exception` 實例，`BaseExceptionGroup` 建構函式會回傳 `ExceptionGroup` 而不是 `BaseExceptionGroup`，因此可以被使用來讓這樣的選擇自動化。另一方面來說，如果任何包含的例外不是 `Exception` 的子類別，`ExceptionGroup` 建構函式會引發 `TypeError`。

  CPython 實作細節： The `excs` parameter may be any sequence, but lists and tuples are specifically processed more efficiently here. For optimal performance, pass a tuple as `excs`.

  message

    建構函式的 `msg` 引數。這是一個唯讀的屬性。

  exceptions

    指定給建構函式 `excs` 序列中的例外組成的元組。這是一個唯讀的屬性。

  subgroup(condition)

    回傳只包含從現有群組比對到 condition 的例外的例外群組，或者當結果為空時回傳 `None`。

    條件式可以是一個例外型別或是例外型別的元組，在此情況下，每個例外都會使用與 `except` 子句中使用的相同檢查方法來檢查是否有匹配。條件式也可以是一個可呼叫物件（除了型別物件之外），其接受一個例外作為單一引數，而如果該例外應該在子群組中就回傳 true。

    現有例外的巢狀結構會保留在結果裡，其 `message`、`__traceback__`、`__cause__`、`__context__` 及 `__notes__` 欄位的值也一樣。空的巢狀群組會從結果裡排除。

    條件會對巢狀例外群組裡的所有例外做檢查，包括頂層及任何巢狀的例外群組。如果條件對這樣的例外群組為 true，它會被完整包含在結果裡。

    在 3.13 版被加入: `condition` 可以是任何不是型別物件的可呼叫物件。

  split(condition)

    像 `subgroup()` 一樣，但回傳一對 `(match, rest)`，其中 `match` 是 `subgroup(condition)` 而 `rest` 是剩下沒有比對到的部分。

  derive(excs)

    回傳有相同 `message` 但將例外包裝在 `excs` 的例外群組。

    此方法被 `subgroup()` 及 `split()` 使用，被用來在各種情境下拆分例外群組。子類別需要覆寫它來讓 `subgroup()` 及 `split()` 回傳子類別而不是 `ExceptionGroup` 的實例。

    `subgroup()` 及 `split()` 會從原始的例外群組複製 `__traceback__`、`__cause__`、`__context__` 和 `__notes__` 欄位到 `derive()` 所回傳的例外群組上，因此這些欄位不需要被 `derive()` 更新。

        >>> class MyGroup(ExceptionGroup):
        ...     def derive(self, excs):
        ...         return MyGroup(self.message, excs)
        ...
        >>> e = MyGroup("eg", [ValueError(1), TypeError(2)])
        >>> e.add_note("a note")
        >>> e.__context__ = Exception("context")
        >>> e.__cause__ = Exception("cause")
        >>> try:
        ...    raise e
        ... except Exception as e:
        ...    exc = e
        ...
        >>> match, rest = exc.split(ValueError)
        >>> exc, exc.__context__, exc.__cause__, exc.__notes__
        (MyGroup('eg', [ValueError(1), TypeError(2)]), Exception('context'), Exception('cause'), ['a note'])
        >>> match, match.__context__, match.__cause__, match.__notes__
        (MyGroup('eg', [ValueError(1)]), Exception('context'), Exception('cause'), ['a note'])
        >>> rest, rest.__context__, rest.__cause__, rest.__notes__
        (MyGroup('eg', [TypeError(2)]), Exception('context'), Exception('cause'), ['a note'])
        >>> exc.__traceback__ is match.__traceback__ is rest.__traceback__
        True

  需注意 `BaseExceptionGroup` 定義了 `__new__()`，因此需要不同建構函式簽名的子類別需要覆寫它而不是 `__init__()`。例如下面定義了一個例外群組子類別接受 exit_code 並從中建構群組的訊息。：

      class Errors(ExceptionGroup):
         def __new__(cls, errors, exit_code):
            self = super().__new__(Errors, f"exit code: {exit_code}", errors)
            self.exit_code = exit_code
            return self

         def derive(self, excs):
            return Errors(excs, self.exit_code)

  像 `ExceptionGroup` 一樣，任何 `BaseExceptionGroup` 的子類別且也是 `Exception` 的子類別只能包裝 `Exception` 的實例。

  在 3.11 版被加入.

## 例外階層

內建例外的類別階層如下：

    BaseException
     ├── BaseExceptionGroup
     ├── GeneratorExit
     ├── KeyboardInterrupt
     ├── SystemExit
     └── Exception
          ├── ArithmeticError
          │    ├── FloatingPointError
          │    ├── OverflowError
          │    └── ZeroDivisionError
          ├── AssertionError
          ├── AttributeError
          ├── BufferError
          ├── EOFError
          ├── ExceptionGroup [BaseExceptionGroup]
          ├── 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
          │    ├── PythonFinalizationError
          │    └── RecursionError
          ├── StopAsyncIteration
          ├── StopIteration
          ├── SyntaxError
          │    └── IndentationError
          │         └── TabError
          ├── SystemError
          ├── TypeError
          ├── ValueError
          │    └── UnicodeError
          │         ├── UnicodeDecodeError
          │         ├── UnicodeEncodeError
          │         └── UnicodeTranslateError
          └── Warning
               ├── BytesWarning
               ├── DeprecationWarning
               ├── EncodingWarning
               ├── FutureWarning
               ├── ImportWarning
               ├── PendingDeprecationWarning
               ├── ResourceWarning
               ├── RuntimeWarning
               ├── SyntaxWarning
               ├── UnicodeWarning
               └── UserWarning