スキルアップ

Python入門:例外と例外対応でプログラムを安全に!

はじめに

Pythonである程度コードが書けるようになってくると、
少しずつ実践的なことに挑戦したくなってきますよね。

私自身も、座学的な知識だけではなく
そろそろポートフォリオや副業に活かせるコードを
書いていこうと思い、
簡単な自動化スクリプトやWebアプリにチャレンジしていました。

実務を意識するうえで必須となるのが、
エラーでプログラムが想定外の挙動をとらないように
考慮することです。

プログラムが予期せぬ動作をとったときに
発生している問題を例外と言います。

どのような時に起こるかというと、
以下が学習したてではよくあります。

  • 入力された値が想定と違っていた
  • 0で割ってしまった
  • 存在しないファイルを開こうとした

こうした例外と呼ばれる問題は、
どんなにシンプルなコードでも起こり得ます。

Pythonにはこれらのエラーをうまく処理し、
落ちにくいコードを書くための仕組みが
しっかり用意されています。

それが今回のテーマである 「例外処理」 となります。

今回は私自身が「これは覚えておくのは必須」と感じた
try-except文の基本から、

  • よくあるエラーの種類
  • エラー発生時の情報の取り出し方
  • 複数の例外処理方法

まで、Pythonにおける例外処理の基礎と実用パターン
まとめていきます。

この記事はこんな方におすすめです!

  • エラーに対して、よくわからないまま print() で
    確認しているという方
  • プログラムが突然止まってしまう経験がある方
  • エラーにも対応できる
    「信頼性の高いコード」を目指したい方
  • 副業や実務でも通じる最低限のエラー対応力を
    身につけたい方


第1章:なぜ例外処理が必要なのか

Pythonのコードを書き始めたばかりの頃は、
学習教材やサンプルコードが正常に動く前提で進んでいくので、
エラーに遭遇することはあまり多くないかもしれません。

でも、いざ自分でコードを書くようになると、
エラーの連発
に襲われることが増えていきます。

たとえば、以下のようなシンプルなコードに
「0」を入力するとどうなるでしょうか?

x = int(input("数字を入力してください: "))
print(10 / x)

プログラムの実行結果は、

ZeroDivisionError: division by zero

となり、この時点で強制終了してしまいます。
これがまさに「例外(エラー)」が発生した状態です。

例外処理が書かれていないコードは、

  • エラー1つで全体が止まる
  • ユーザー体験が悪くなる
  • 実務では信用されないコードになる

一方で、例外処理をしっかり書くと、

  • 起こりうる問題に備えられる
  • 予測不能な動きが減る
  • ユーザーにもわかりやすい
    エラーメッセージを出せる

このように、例外処理は「強いコード」への第一歩となります。


そもそも例外とは

例外とは、コード自体に文法的な間違いはないけど、
実行時に想定外の問題が起きてしまった状態を指します。

  • 存在しないファイルを開こうとした
  • リストの範囲外の要素を参照した
  • ゼロ除算をしてしまった
  • 文字列を数値に変換しようとした など

これらはすべて、プログラム実行時に発生する
実行時エラー(Runtime Error)です。


try-except で“強制終了されない”コードに変える

先ほど、例として取り上げた「0除算」でエラーになるコードに、
例外処理を加えてみるとどうなるでしょうか。

try:
    x = int(input("数字を入力してください: "))
    print(10 / x)
except ZeroDivisionError:
    print("0で割ることはできません!")

例外処理の書き方は、次の章で詳しくまとめますが、
このように書くだけで、エラーが発生しても
プログラムが強制終了することはなくなります。

また、「0で割ることはできません!」
というメッセージを表示し、
何が起きたかをわかりやすく伝えることもできます。

これが「例外処理」の力です。


第2章:try-except構文

Pythonの例外処理はとてもシンプルでありながら柔軟性が高く、
少し使い方を知るだけで、実用レベルの堅牢なコード
書けるようになります。

基本構文として、

try:
    # エラーが起こるかもしれない処理
except エラーの種類:
    # エラーが起きたときの処理

たとえば、整数の入力を求める場面で
よくある「型変換エラー」の対処を見てみましょう。

try:
    age = int(input("年齢を入力してください: "))
except ValueError:
    print("数字を入力してください!")

このように、エラーが発生する可能性
のある処理を try: に入れ、
その後 except: でエラーを補足して、
プログラムを止めずに処理を続けることができます。


複数のエラーを補足する

場合によっては、1つの処理の中で
複数の種類の例外が起こることもあります。

try:
    num = int(input("数字を入力してください: "))
    result = 10 / num
except ValueError:
    print("整数を入力してください。")
except ZeroDivisionError:
    print("0では割れません!")

このように except を複数並べることで、
エラーごとに異なる対応ができます。


すべての例外をまとめて処理する

場合によっては、「どんなエラーでもいいから一括で処理したい」
という場面もあります。
そんなときは、except: のあとに
エラーの種類を指定せずに使うこともできます。

try:
    # いろいろな処理
except:
    print("予期しないエラーが発生しました。")

ただしこれはすべてのエラーを飲み込んでしまうため、
本来気づくべきバグも見逃してしまう恐れがあります。

実務や副業で使うコードでは、
エラーの種類を明示的に指定するのが原則です。


例外情報を変数として取得する

Pythonでは、例外の詳細情報を取得してログに残したい場合、
as を使ってエラーオブジェクトを受け取ることができます。

try:
    with open("data.txt") as f:
        content = f.read()
except FileNotFoundError as e:
    print(f"ファイルが見つかりませんでした: {e}")

こうすることで、エラーの内容を
ユーザーやログに具体的に出力
できて、
あとで調査しやすくなります。


else / finallyでの例外処理

try の後に、except だけでなく
elsefinally を組み合わせることもできます。

elseは例外が出なかったときだけ
実行されるブロックとして記述します。

try:
    num = int(input("整数を入力: "))
except ValueError:
    print("数字じゃないです!")
else:
    print(f"あなたの入力は {num} です。")

また、finallyは例外が起きても起きなくても、
必ず最後に実行したい処理を記述します。

try:
    print("処理中...")
    1 / 0
except ZeroDivisionError:
    print("エラー発生")
finally:
    print("終了処理します")

finallyファイルのクローズ処理や接続の切断処理など、
最後に必ず行いたい処理を書く場所として便利です。


第3章:よくある例外の種類と特徴

Pythonでプログラムを書いていると、
初心者のうちは、特に高確率で遭遇する
「お決まりのエラー」があります。

この章では、私自身も実際に遭遇したエラーを中心に、
よく出る例外の種類とその意味、原因、対処方法
をまとめていきます。


ValueError:型が違う

代表的なケースとしては、
想定されている引数の型と
実際の受け渡された型が違う場合に発生します。

age = int("twenty")
  • int() に文字列 "twenty"
    渡しているため、
    数字に変換できずにエラー発生
  • try-except で補足して、
    入力を再促す
    のが一般的な対処法

ZeroDivisionError:0で割られている

除算時に、0で割った場合に発生します。

result = 10 / 0
  • 除算前に分母が0でないかifで判定する
  • または try-except で包んで、
    安全な処理に切り替える

FileNotFoundError:ファイルが見つからない

open関数など、ファイル操作をする際に
対象のファイルが存在していない場合に発生します。

with open("not_exist.txt") as f:
    content = f.read()
  • 例外発生時の見直しポイントは、
    ファイルのパスが正しいか確認
  • コードとしては存在確認をしてから読み込む、
    または try-except で補足

IndexError:範囲外の要素を参照

リストやタプルなど、indexを用いてアクセスする変数にたいして
存在していないindexや範囲外の値を指定することで発生します。

lst = [1, 2, 3]
print(lst[5])
  • len関数でリストの長さを確認してからアクセス
  • もしくは try-except で回避

KeyError:存在しないキーを参照

ディクショナリにおいて、存在していないキーで
要素を取得しようとすることで発生します。

data = {"name": "Taro"}
print(data["age"])
  • dict.get("key") を使えば、
    存在しないキーでも None
    返してくれるので安全

第4章:raise文とassert文を使ったエラー制御

前の章までで「起こってしまったエラーへの対処法」
を学びましたが、
今度は 「あえて自分でエラーを起こす」
という考え方を紹介します。

実は意図的にエラーを出すことで、
コードの信頼性を高めることも可能です。

ポイントとして、

  • raise を使えば、
    自分のルールに違反する入力に対して
    明示的に例外を出せる
  • assert を使えば、前提条件を
    簡潔にチェックできる
    (主にテストやデバッグ用)
  • どちらも「コードの信頼性や保守性」を
    高めるために重要なツール

raise文:自分で例外を発生させる

raise 文は、
「ここで明示的に例外を発生させたい」
というときに使います。

例として、年齢が0以下なら例外を出すといった場合です。

def set_age(age):
    if age <= 0:
        raise ValueError("年齢は正の整数である必要があります。")
    print(f"年齢は {age} 歳です。")

このように、業務ルールやビジネスロジックに
合わない値を防ぐ目的
で使われます。

よくある使いどころとしては、

  • 数値が負の値であってはいけない場合
  • 必須のデータが渡されていないとき
  • 特定の条件が成立していないと処理できない場合

assert文:前提条件をチェックする

assert 文は、
「この条件が真であるべきだ!」
というときに使います。
条件が False の場合、
自動的に AssertionError を発生させます。

例として、リストの長さを事前にチェックする場合などです。

data = [1, 2]
assert len(data) == 3, "リストの長さが正しくありません"

条件がFalseだった場合、以下のような出力となります。

AssertionError: リストの長さが正しくありません

assertを使うポイントとして、

  • デバッグやテスト時のチェック用に使うのが基本
  • 本番環境では python -O オプションを使うと
    assert は無視される(注意)

第5章:例外処理のベストプラクティスと注意点

Pythonの例外処理には非常に柔軟な機能がありますが、
自由度が高いぶん、避けたほうが良い使い方も存在します。

私自身も実際にやりがちだった失敗例も交えながら、
例外処理のベストプラクティスと注意点を紹介します。


ベストプラクティス(やるべきこと)

1. 具体的な例外クラスを補足する

# NG例(Exceptionでなんでもキャッチ)
try:
    process()
except Exception:
    print("なんかエラー")

# OK例(具体的なエラーを補足)
try:
    process()
except ValueError:
    print("値が不正です")

2. 最小限の範囲でtry-exceptを使う

# NG例(tryの範囲が広すぎる)
try:
    a = int(input("数値を入力: "))
    b = a * 2
    print(b)
except ValueError:
    print("数値を入力してください")

# OK例(最小限の処理をtryに)
try:
    a = int(input("数値を入力: "))
except ValueError:
    print("数値を入力してください")
else:
    b = a * 2
    print(b)

3. ログ出力や再raiseで情報を残す

try:
    do_something()
except ValueError as e:
    print(f"エラー発生: {e}")
    raise  # 再スローして上位で処理

避けるべき例外処理

1. すべての例外を無視する

try:
    dangerous_code()
except:
    pass  # これは危険!

エラーがあっても気づかないコードになります。
必ず原因の把握や、ログ出力をするべきです。


2. Exceptionで全部キャッチしてそのまま続行

try:
    something()
except Exception:
    print("なんか失敗したけど、まぁいいか")

原因が不明瞭なまま続行すると、
致命的なバグが埋もれやすくなります。


3. 複雑なロジックをtryブロックにまとめすぎる

tryの中で複数の処理をまとめてしまうと、
どの処理が原因かわからなくなります。
必ず、「失敗する可能性のある最小単位」に
try-exceptをかけると原因がわかりやすくなります。


第6章:まとめ & 次回予告

今回は「例外処理」をテーマに、
エラーに強いコードの書き方について学んできました。

学び始めのうちは難しそうに見えるかもしれません。
それでも、ひとつひとつの構文や考え方を理解すれば、
確実に自信を持って扱えるようになります。

特に私が学んで感じたのは、
try-except構文の柔軟さと、
raiseやassertによる制御の便利さ
です。

また、例外処理はエラーを防ぐためだけでなく、
ユーザーや開発者に正しくエラーを伝えるためにも
大切な役割を果たしています。

今回の学びポイント

  • try-except 構文でエラーをキャッチし、
    安全に処理を継続できる
  • raise で意図的に例外を出すことで、
    ルール違反を事前に検知できる
  • assert はデバッグやテスト用の
    便利なチェックツール
  • 入力処理やファイル操作には、
    具体的なエラーを想定した設計が重要

ここまでで、Pythonの基本文法を一通り学んできたので、
次に取り組むのは 、ポートフォリオとして
実践的なWebアプリ開発をしていこうと考えています。

そこで選んだのが、Pythonの人気Webフレームワークである
Django(ジャンゴ)

次回からは以下のようなテーマを扱っていく予定です。

  • Djangoとはどんなフレームワーク?
  • Webアプリ開発の全体像とは?
  • なぜDjangoを学ぶのか?Flaskとの違いは?
  • Djangoでどんなポートフォリオを作るのか?

これまで学んできた知識をどう活かせるのか、
私自身の“実践記”として、リアルな気づきとともに
発信していきたいと思います。

▶次回の記事はこちら:
[現在準備中です!少々お待ちください!]

-スキルアップ