Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Python辞典

  1. トップページ
  2. Python辞典
  3. raise / 独自例外クラス

raise / 独自例外クラス

『raise』は意図的に例外を発生させるキーワードです。独自の例外クラスを定義することで、ライブラリや自作モジュール固有のエラーを明確に表現できます。独自例外クラスは必ずExceptionまたはその適切なサブクラスを継承して作ります。BaseExceptionを直接継承するのは特殊な用途を除いて避けましょう。

構文
# 例外を発生させる
raise 例外クラス("メッセージ")

# 別の例外を原因として連鎖させる
raise 新しい例外 from 元の例外

# 現在の例外を再送出(exceptブロック内)
raise

# 独自例外クラスの定義
class MyError(Exception):
    pass

class MyDetailedError(Exception):
    def __init__(self, message, code):
        super().__init__(message)
        self.code = code
構文・クラス一覧
構文・クラス概要
raise 例外(msg)例外を発生させる。exceptブロック外で使う。
raise現在の例外を再送出する。exceptブロック内でのみ使える。
raise 新例外 from 旧例外例外を別の例外に変換しながら、元の原因も保持する。
class MyError(Exception)Exceptionを継承した独自例外クラスを定義する。
super().__init__(msg)親クラスの__init__を呼び出してメッセージを設定する。
サンプルコード
# raise: 基本的な例外の発生
def divide(a, b):
    if b == 0:
        raise ZeroDivisionError("ゼロ除算は禁止されています")
    return a / b

try:
    divide(10, 0)
except ZeroDivisionError as e:
    print(e)    # ゼロ除算は禁止されています

# raise from: 例外の連鎖(原因を保持)
def load_config(path):
    try:
        with open(path) as f:
            return f.read()
    except FileNotFoundError as e:
        raise RuntimeError(f"設定ファイルの読み込みに失敗: {path}") from e

try:
    load_config('config.json')
except RuntimeError as e:
    print(e)            # 設定ファイルの読み込みに失敗: config.json
    print(e.__cause__)  # 元のFileNotFoundError

# シンプルな独自例外クラス
class ValidationError(Exception):
    pass

class AgeError(ValidationError):
    pass

def validate_age(age):
    if not isinstance(age, int):
        raise TypeError(f"年齢は整数で指定してください: {type(age).__name__}")
    if age < 0:
        raise AgeError(f"年齢は0以上で指定してください: {age}")
    if age > 150:
        raise AgeError(f"年齢が大きすぎます: {age}")
    return age

try:
    validate_age(-5)
except AgeError as e:
    print(f"年齢エラー: {e}")

# 詳細情報を持つ独自例外
class HttpError(Exception):
    def __init__(self, message, status_code):
        super().__init__(message)
        self.status_code = status_code

    def __str__(self):
        return f"[{self.status_code}] {super().__str__()}"

def fetch(url):
    if not url.startswith('https://'):
        raise HttpError("HTTPSのみ許可されています", 400)

try:
    fetch('http://example.com')
except HttpError as e:
    print(e)                    # [400] HTTPSのみ許可されています
    print(e.status_code)        # 400
概要

独自例外クラスを使うことで、エラーの種類をコードで表現できます。例えばWebアプリなら『HttpError』、バリデーション処理なら『ValidationError』といった形でエラーを分類することで、呼び出し側が必要な例外のみを捕捉できます。

『raise 新例外 from 旧例外』は例外チェーンと呼ばれ、低レイヤーの例外を高レイヤーの例外に変換しながら、元の原因を『__cause__』属性として保持します。raise from を使わず raise するとPythonは自動で__context__に元の例外を保持しますが、意図的な変換には from を明示する方が推奨されます

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。