Python raise文の使い方

この記事のポイント

通常、例外(エラー)はプログラムの文法ミスや実行時の問題によって自動で発生します。

Pythonのraise文は、そうした自動的なエラーとは異なり、開発者自身が特定の状況になったら、あえてエラーとして処理を中断させたい場合に使用します。

この記事を読むと、次のようなことが身に付きます。

  • raise文の基本的な使い方とエラーを発生させる仕組み
  • 状況に応じた例外クラス(ValueErrorなど)の使い分け方
  • 独自の例外(カスタム例外)を作成して使う方法

raise文を使いこなすことで、プログラムが予期しない状態になるのを防ぎ、問題の発見しやすい、品質の高いコードを書けるようになります。

目次

raise文とは?

raise文とは、プログラムの実行中に意図的に例外(エラー)を発生させるための命令です。

通常、例外は文法ミスや実行時の問題が起きたときに自動で発生します。ですが、raise文を使うと、開発者自身が「ここで問題が起きた」とプログラムに知らせることができます。

例えば、スポーツの試合でルール違反があったときに、審判が笛を吹いて試合を中断させるようなイメージです。

プログラムにおいて、不正な値が入力された場合や、想定外の状況になった場合に、あえてエラーを発生させて実行を制御するために使われます。

raise文の特徴

  • 不正な値の入力時など、特定の条件で意図的に例外を発生させられる
  • ValueErrorやTypeErrorといった例外クラスを指定し、エラー内容を明確にできる
  • プログラムが異常な状態のまま続行するのを防ぐことができる
  • エラーの原因特定がしやすくなり、デバッグの効率化につながる
  • コードの品質や保守性を高めるのに役立つ

【関連】
Pythonをもっと詳しく学ぶならpaizaラーニング

基本構文

raise文の基本的な使い方は、raiseキーワードの後に、発生させたい例外の種類を指定するだけです。

Pythonにはあらかじめ多くの例外クラス(ValueErrorやTypeErrorなど)が用意されているため、状況に合ったものを指定します。例外クラスを指定するときに、()の中にエラーメッセージを入れると、エラー発生時になぜ問題が起きたのかを分かりやすく伝えられます。

まずは、関数にマイナスの数が渡された場合にValueErrorを発生させる例を見てみましょう。

def check_positive(number): if number < 0: raise ValueError("負の数は受け付けません") return number * 2 result = check_positive(5) print(result)

出力結果

10

この例では、check_positive(5)として正の数5を渡しているため、if文の条件(number < 0)に当てはまりません。そのため、raise文は実行されず、number * 2の結果である10が表示されます。もしcheck_positive(-5)のように負の数を渡すと、raise文が実行され、プログラムはValueErrorで停止します。

次に、発生させた例外をtry...except文で処理する例を紹介します。raise文で発生した例外も、通常の例外と同じようにexceptで受け取ることができます。

def divide_numbers(a, b): if b == 0: raise ZeroDivisionError("ゼロで割ることはできません") return a / b try: result = divide_numbers(10, 0) except ZeroDivisionError as e: print(f"エラーが発生しました: {e}")

出力結果

エラーが発生しました: ゼロで割ることはできません

この例では、divide_numbers(10, 0)が呼び出されると、関数内のif b == 0:の条件に当てはまります。raise ZeroDivisionError(...)が実行され、例外が発生します。

tryブロック内で例外が発生したため、プログラムは停止せず、except ZeroDivisionErrorブロックに処理が移ります。as eで例外オブジェクトを受け取りエラーメッセージを表示しています。

実用例

ここからは、実際の開発現場で役立つraise文の具体的な使用例を紹介していきます。それぞれのサンプルコードでは、異なるシナリオでの例外処理の実装方法を示しており、初心者の方でもすぐに自分のプロジェクトに応用できる内容になっています。

各コード例では動物をテーマにした出力結果を用いることで、より親しみやすく理解しやすい形で解説します。

入力値検証での例外発生

関数が受け取る引数が正しいかどうかをチェックし、不正な値が渡された場合に例外を発生させる、最も基本的な使い方です。

def create_animal_profile(name, age): if not isinstance(name, str) or not name: raise ValueError("動物の名前は空でない文字列である必要があります") if not isinstance(age, int) or age < 0: raise ValueError("年齢は0以上の整数である必要があります") return f"{name}は{age}歳です" profile = create_animal_profile("ネコ", 3) print(profile)

出力結果

ネコは3歳です

この例では、関数が呼び出されたときに、まず引数のnameとageを検証しています。nameが文字列でない場合や空の文字列の場合、またはageが整数でない場合や0未満の場合には、ValueErrorを発生させます。今回は("ネコ", 3)という正しい引数を渡しているため、チェックを通過し、プロフィールの文字列が返されます。

既存の例外を再送出する方法

exceptブロックで例外を受け取った後、ログの記録など何らかの処理を行い、その例外をもう一度raiseで発生させる使い方です。関数内で起きたエラーを、その関数の呼び出し元にも知らせたい場合に使います。

def process_animal_data(animal_type): try: if animal_type not in ["イヌ", "ネコ", "トリ"]: raise KeyError(f"{animal_type}は登録されていません") except KeyError: print("エラーをログに記録しました") raise try: process_animal_data("ウサギ") except KeyError as e: print(f"最終的なエラー処理: {e}")

出力結果

エラーをログに記録しました
最終的なエラー処理: ウサギは登録されていません

この例では、process_animal_data("ウサギ")を呼び出すと、animal_typeがリストにないためKeyErrorが発生します。except KeyErrorブロックが実行され、「エラーをログに記録しました」と表示されます。

その後、raiseが実行され、受け取ったKeyErrorがそのまま再度発生します。呼び出し元のtryブロックで例外が起きたことになるため、外側のexcept KeyErrorブロックが実行され、「最終的なエラー処理」が表示されます。

カスタム例外クラスの作成

ValueErrorなどの組み込み例外ではなく、自分で定義した独自の例外クラスを発生させることもできます。プログラム固有のエラー(例:動物が見つからないエラー)を分かりやすく表現できます。

class AnimalNotFoundError(Exception): pass def find_animal(animal_id, database): if animal_id not in database: # 独自に定義した例外を発生させる raise AnimalNotFoundError(f"ID {animal_id}の動物は見つかりません") return database[animal_id] animals = {1: "ライオン", 2: "ゾウ"} try: # 1. 成功するケース result_ok = find_animal(1, animals) print(f"見つかった動物 (ID: 1): {result_ok}") # 2. 失敗するケース(例外が発生する) print("次にID: 3を探します...") result_ng = find_animal(3, animals) print(f"見つかった動物 (ID: 3): {result_ng}") # この行は実行されません except AnimalNotFoundError as e: print(f"エラーが発生しました: {e}")

出力結果

見つかった動物 (ID: 1): ライオン
次にID: 3を探します...
エラーが発生しました: ID 3の動物は見つかりません

この例では、まずclass AnimalNotFoundError(Exception):で独自の例外クラスを定義しています。find_animal関数は、animal_idがdatabaseに存在しない場合に、AnimalNotFoundErrorを発生させます。

tryブロックでは、最初にfind_animal(1, ...)を呼び出し、ID 1(ライオン)が無事に見つかるため、結果が表示されます。次にfind_animal(3, ...)を呼び出すと、ID 3はdatabaseに存在しないため、raise文が実行されAnimalNotFoundErrorが発生します。

tryブロック内で例外が発生したため、処理はexcept AnimalNotFoundErrorブロックに移り、エラーメッセージが表示されます。

条件付き例外発生の実装

複数の条件をチェックし、問題のある条件に応じて異なる種類の例外を発生させる使い方です。

def calculate_animal_food(weight, animal_type): if weight <= 0: raise ValueError("体重は正の数である必要があります") if animal_type not in ["草食", "肉食"]: raise TypeError("動物タイプは草食または肉食を指定してください") multiplier = 0.05 if animal_type == "草食" else 0.03 return weight * multiplier food_amount = calculate_animal_food(50, "草食") print(f"必要な餌の量: {food_amount}kg (シカの場合)")

出力結果

必要な餌の量: 2.5kg (シカの場合)

この例では、calculate_animal_food関数が2つの検証を行っています。まずweightが0以下であればValueErrorを発生させます。次にanimal_typeが指定されたリストに含まれていなければTypeErrorを発生させます。

今回は(50, "草食")と正しい引数を渡しているため、どちらのraise文も実行されず、計算結果が正しく返されます。

例外メッセージのカスタマイズ

状況に応じてエラーメッセージの内容を動的に組み立て、デバッグをしやすくする方法です。

def register_animal(name, species, habitat): errors = [] if not name: errors.append("名前が空です") if not species: errors.append("種別が空です") if habitat not in ["陸上", "水中", "空中"]: errors.append("生息地が不正です") if errors: raise ValueError(f"登録エラー: {', '.join(errors)}") return f"{name}({species})を登録しました" result = register_animal("ペンギン", "鳥類", "水中") print(result)

出力結果

ペンギン(鳥類)を登録しました

この例では、register_animal関数が複数の入力項目を一度にチェックしています。問題が見つかるたびにerrorsにエラーメッセージを追加します。全てのチェックが終わった後、errorsが空でなければ、raise ValueErrorでまとめてエラーを報告します。

今回は正しい引数を渡しているため、errorsリストは空のままで、raise文は実行されず、登録成功のメッセージが返されます。

複数の例外を連鎖させる処理

ある例外(例:FileNotFoundError)を原因として別の例外(例:RuntimeError)を発生させるには、raise ... from ...構文を使います。例外を連鎖させることで根本原因の追跡に役立ちます。

def load_animal_config(filename): try: with open(filename) as f: return f.read() except FileNotFoundError as e: raise RuntimeError(f"設定ファイルの読み込みに失敗しました") from e try: config = load_animal_config("animals.txt") except RuntimeError as e: print(f"エラー: {e}") print(f"元の例外: {e.__cause__}")

出力結果

エラー: 設定ファイルの読み込みに失敗しました
元の例外: [Errno 2] No such file or directory: 'animals.txt'

この例では、存在しないファイル"animals.txt"を開こうとしているため、tryブロック内でFileNotFoundErrorが発生し、exceptブロックが実行されます。

raise RuntimeError(...) from eにより、FileNotFoundError(変数e)を原因(__cause__)とするRuntimeErrorが新たに発生します。呼び出し元ではRuntimeErrorを捕捉し、そのメッセージと、e.__cause__(元の例外)の両方を表示しています。

例外からの回復処理

raiseで発生させた例外をあえてtry...exceptで捕捉し、代替の処理(デフォルト値を返すなど)を実行することで、プログラムを停止させずに継続させる方法です。

def get_animal_sound(animal): sounds = {"イヌ": "ワンワン", "ネコ": "ニャー"} try: if animal not in sounds: raise KeyError(f"{animal}の鳴き声は登録されていません") return sounds[animal] except KeyError: return "不明な鳴き声" print(f"イヌの鳴き声: {get_animal_sound('イヌ')}") print(f"ウマの鳴き声: {get_animal_sound('ウマ')}")

出力結果

イヌの鳴き声: ワンワン
ウマの鳴き声: 不明な鳴き声

この例では、get_animal_sound関数内でanimalがsoundsに存在するかどうかをチェックしています。get_animal_sound('イヌ')の場合はKeyErrorが発生せず、鳴き声が返されます。

get_animal_sound('ウマ')の場合は登録されていないためKeyErrorが発生し、try...exceptでKeyErrorを捕捉し、exceptブロックで"不明な鳴き声"という文字列を返して処理を終えています。そのため、プログラムは停止しません。

まとめ

Pythonのraise文は、意図的に例外を発生させ、プログラムの品質を高めるために重要な命令です。この記事では、基本的な使い方から独自の例外クラスの作成まで解説しました。

raise文が活用できるような場面は次のようなケースです。

raise文が活躍する場面

  • 入力値が不正なときに処理を中断させたいとき
  • 関数の仕様(ルール)違反を呼び出し元に伝えたいとき
  • プログラム固有のエラーを分かりやすく定義したいとき

raise文を用いる上で、押さえておきたいポイントを覚えておきましょう。

重要なポイント

  • ValueErrorなど、状況に合う例外クラスを選ぶ
  • エラーメッセージには原因がわかる情報を含める
  • raise fromでエラーの根本原因を追跡する

初めてPythonを学ぶ方も、この記事で紹介したraise文を実際に書いて、基本的な使い方を試してみてください。

意図的にエラーを発生させる処理は、安全なプログラムを作る上で欠かせません。

ぜひraise文をマスターして、より品質の高い実用的なプログラムを作成できるようになりましょう。

レベルを更に上げたい方はpaizaプログラミングスキルチェックへ

  1. paizaラーニングトップ
  2. リファレンス
  3. Pythonのリファレンス記事一覧
  4. Python raise文の使い方