結論から言うと、raise は「このまま処理を続けると危ない」と判断した場所で、自分からエラーを発生させるために使います。
Pythonでは、存在しないファイルを開いたときのように、Python側が自動でエラーを出してくれる場面があります。
一方で、「金額が0以下なら処理したくない」「必須項目が空なら登録したくない」といった業務ルールは、Pythonだけでは判断できません。
この記事では、自分でエラーを出す raise の基本を、動くコードと一緒に整理します。
この記事でわかること
完成コード
完成コードは次の通りです。
def calculate_total_price(unit_price: int, quantity: int) -> int:
if unit_price <= 0:
raise ValueError("単価は1以上で指定してください")
if quantity <= 0:
raise ValueError("数量は1以上で指定してください")
return unit_price * quantity
orders = [
{"item": "ノート", "unit_price": 120, "quantity": 3},
{"item": "ペン", "unit_price": 80, "quantity": 0},
{"item": "ファイル", "unit_price": 150, "quantity": 2},
]
for order in orders:
try:
total = calculate_total_price(order["unit_price"], order["quantity"])
except ValueError as error:
print(f"{order['item']} は計算できません: {error}")
else:
print(f"{order['item']}: {total}円")コードのポイント
このコードでは、単価と数量から合計金額を計算しています。
- 単価が0以下なら
ValueErrorを発生させています - 数量が0以下の場合も
ValueErrorを発生させています - 呼び出し側では
tryとexceptでエラーを受け止めています - 正常に計算できた場合だけ、合計金額を表示しています
raise を使うと、処理できない理由をその場で明確にできます。
不正な値のまま計算を続けて、後から原因が分かりにくくなるのを防げます。
コードを順番に説明します
主要な処理を分けて説明します。
1. 処理できない条件を先に確認します
if unit_price <= 0:
raise ValueError("単価は1以上で指定してください")この部分では、単価が0以下ではないかを確認しています。
合計金額の計算では、単価が0円やマイナスになると、通常の注文データとして扱いにくくなります。
このような条件は、処理の途中ではなく、関数の入り口で確認すると読みやすくなります。
問題のある値を早めに止めることで、後続の処理をシンプルに保てます。
2. raise で例外を発生させます
raise ValueError("単価は1以上で指定してください")raise の後ろには、発生させたい例外を書きます。
この例では、値の中身が処理の条件に合わないため ValueError を使っています。
エラーメッセージには、何が問題で、どのように直せばよいかを短く書くと親切です。"エラーです" だけでは原因が分かりにくいため、実務では避けたほうがよいです。
3. 呼び出し側で例外を受け止めます
try:
total = calculate_total_price(order["unit_price"], order["quantity"])
except ValueError as error:
print(f"{order['item']} は計算できません: {error}")
else:
print(f"{order['item']}: {total}円")raise で発生した例外は、呼び出し側の except で受け止められます。
この例では、1件の注文に問題があっても、そこでプログラム全体を止めず、次の注文へ進める形にしています。
else は、例外が起きなかった場合だけ実行されます。
エラー時の処理と、正常時の処理を分けたいときに使うと読みやすくなります。
実務で使うときのポイント
実務で raise を使う場面は、入力値や処理条件を満たしていないときです。
- 必須項目が空のまま渡された
- 金額や数量が0以下になっている
- 設定値が想定した候補に入っていない
- 処理対象の状態が、次の処理に進めない状態になっている
大切なのは、raise を「プログラムを壊すため」ではなく、「不正な状態を早く知らせるため」に使うことです。
問題のある値を黙って処理すると、間違った集計結果や壊れたファイルを作ってしまうことがあります。
第4章の前半で扱った try、except、finally と組み合わせると、失敗する場所と受け止める場所を分けられます。
この次の 4-5 では、TypeError と ValueError の違いを整理すると、どの例外を選ぶべきか判断しやすくなります。