このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

【Python入門】例外を発生させるraise文

例外を発生させるraise文

 プログラム内で意図的にエラーを発生させることで、特定の条件下で処理を中断させたり、エラー情報を明示的に伝達することが可能になります。raise文を使うと、たとえば不正な入力やビジネスロジックに基づく異常状態を検出したときに、明確なエラーメッセージとともに例外を送出することができます。また、既存の例外を捕捉した上で再送出(リレイズ)することもでき、エラーの原因をチェーンすることも可能です。
 ここでは、raise文の基本的な使い方と、その活用例として銀行口座(BankAccount)クラスを用いた実践例を解説します。

プログラムのダウンロード

 「ダウンロード」から、JupyterLab で実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。

1.raise文の基本

1.1. raise文の役割

 raise文は、プログラムの実行中に意図的に例外を発生させるために使用します。これにより、特定のエラー条件が発生した場合に、エラーハンドリングの仕組みに制御を移すことができます。
 例えば、ある条件下で処理を中断させたい場合や、エラー原因を明示的に通知したい場合に、raise文を用います。

1.2. raise文の書き方

raise文の基本的な構文は以下の通りです。

raise Exception              # 単に Exception を発生させる
raise Exception("message")   # 例外オブジェクトにメッセージを格納して発生させる

さらに、except節内で例外を捕捉した後、再送出する場合は以下のように記述します。

except SomeError as e:
    raise                   # 捕捉した例外をそのまま再送出する

また、既存の例外を原因として新たな例外を発生させるには、from キーワードを用います。

except SomeError as e:
    raise NewError("message") from e

以下の表は、raise文の使用例をまとめたものです。

使用例説明
raise ExceptionException クラスの例外を発生させる。
raise Exception("Invalid value")メッセージ付きの例外を発生させる。
raiseexcept節内で捕捉した例外を再送出する。
raise NewError("message") from e捕捉した例外 e を原因として新たな例外を送出する。

2.実践例:BankAccountクラスを用いた例外の発生

 ここでは、銀行口座(BankAccount)クラスを例に、負の預金額が入力された場合にraise文を用いて例外を発生させる方法を解説します。

2.1. BankAccountクラスの基本

 BankAccountクラスは、口座残高を保持し、預金や引き出しの操作を行います。預金額が負の場合は不正な操作とみなし、raise文で例外を発生させます。

class BankAccount:
    def __init__(self, owner, balance):
        self.owner = owner
        # 初期残高が負の場合、例外を発生させる
        if balance < 0:
            raise Exception("入金額は負でない必要があります。")
        self.balance = balance

    def deposit(self, amount):
        # 預金額が負の場合も例外を送出する
        if amount < 0:
            raise Exception("入金額は負でない必要があります。")
        self.balance += amount
        print(f"Deposited {amount}. New balance: {self.balance}")

    def withdraw(self, amount):
        # 引き出し額が負の場合は例外を発生
        if amount < 0:
            raise Exception("引き出し金額は負でない必要があります。")
        if amount > self.balance:
            raise Exception("資金が不足しています。")
        self.balance -= amount
        print(f"Withdrew {amount}. New balance: {self.balance}")

解説

  • __init__ メソッドでは、初期残高が負の場合にraise文を用いて例外を送出しています。
  • deposit メソッドでは、負の預金額を受け付けないように、同様にraise文を使用してエラーを発生させます。
  • withdraw メソッドでは、引き出し額が負または残高を超える場合に例外を発生させ、正常な操作が行われた場合のみ残高を更新し、その結果を表示します。

2.2. raise文を使った例外処理の実践

 以下のサンプルプログラムでは、ユーザーから預金や引き出しの操作を入力させ、異常な操作が行われた場合にraise文で発生させた例外をexcept節で捕捉し、エラーメッセージを表示します。

while True:
    try:
        # 銀行口座の初期設定
        owner = input("アカウント所有者を入力: ")
        initial_balance = float(input("初期残高を入力してください: "))
        account = BankAccount(owner, initial_balance)
        print(f"Account for {owner} created with balance {account.balance}.")
        
        # 操作の選択
        action = input("Enter 'd' to deposit, 'w' to withdraw, or 'q' to quit: ").lower()
        if action == 'q':
            break
        elif action == 'd':
            amount = float(input("入金額を入力してください: "))
            account.deposit(amount)
        elif action == 'w':
            amount = float(input("出金額を入力してください: "))
            account.withdraw(amount)
        else:
            print("無効なアクションです。")
    except Exception as e:
        # 発生した例外の内容を表示する
        print("Error:", e)
    finally:
        print("-" * 30)

実行結果

アカウント所有者を入力:  taro
初期残高を入力してください:  10000
Account for taro created with balance 10000.0.
Enter 'd' to deposit, 'w' to withdraw, or 'q' to quit:  d
入金額を入力してください:  1000
Deposited 1000.0. New balance: 11000.0
------------------------------
アカウント所有者を入力:  hanako
初期残高を入力してください:  3000
Account for hanako created with balance 3000.0.
Enter 'd' to deposit, 'w' to withdraw, or 'q' to quit:  d
入金額を入力してください:  -2000
Error: 入金額は負でない必要があります。
------------------------------
アカウント所有者を入力:  jiro
初期残高を入力してください:  5000
Account for jiro created with balance 5000.0.
Enter 'd' to deposit, 'w' to withdraw, or 'q' to quit:  w
出金額を入力してください:  10000
Error: 資金が不足しています。
------------------------------

解説

  • ユーザーから口座所有者名と初期残高を入力し、BankAccountオブジェクトを生成します。
  • 初期残高が負の場合、__init__メソッド内でraise文が実行され、例外が発生します。
  • その後、ユーザーの操作(預金または引き出し)を受け付け、各メソッド内で不正な操作があればraise文により例外が発生し、except節でキャッチされます。
  • except節では、例外オブジェクトeを利用して、具体的なエラーメッセージを表示します。
  • finally節は、例外の有無にかかわらず、常に30個のハイフンを表示して区切りを入れ、次の操作に備えます。

まとめ

 raise文は、特定の条件下で意図的に例外を発生させ、プログラムの誤動作や不正な操作を防ぐための強力なツールです。

  • raise文を使うことで、エラー条件が満たされた場合に即座に例外を送出し、エラーハンドリングへ制御を移せます。
  • raise文は、単に例外を送出するだけでなく、例外オブジェクトに情報を格納することも可能です。
  • さらに、except節内でraise文を使い、捕捉した例外を再送出したり、別の例外を連鎖させることもできます。

 これらの機能を適切に活用することで、堅牢で保守性の高いプログラムを作成することが可能となります。