Keep your place in this quest

Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.

エラーはどんなプログラムにも避けられないもので、Pythonではそれらに対処するためのいくつかの方法が用意されています。
エラーハンドリングは、予期しないことが起きた時でもプログラムが安全かつ効率的に実行を続けられるようにするために非常に重要です。

このレッスンでは、エラーの種類、それらの対処方法、自分でエラーを発生させる方法、そして重要な後始末処理を必ず実行させる方法を学びます。


Pythonにおけるエラーの種類

エラーハンドリングを学ぶ前に、2つの主なカテゴリを理解しましょう:

  • 構文エラー(Syntax Errors): Pythonのコードが文法的に正しくない場合に発生し、プログラムが実行される前にPythonインタープリタによって検出されます。
    例:if文の後にコロンを忘れる。

  • 例外(Exceptions): プログラムの実行中に予期せぬことが起こった場合に発生します。例えば、0で割り算したりリストの無効なインデックスにアクセスしようとしたときなどです。

tryexcept を使った例外処理

Pythonで例外を扱う最も一般的な方法は try/except ブロックです:

  • try ブロックは例外が発生する可能性のあるコードを含みます。
  • except ブロックは例外が発生したときに実行されるコードを含みます。

例:

try:
    file = open("file.txt", "r")
    content = file.read()
    print(content)
except IOError:
    print("ファイルを開くことができませんでした。")

ここでは:

  • "file.txt"が存在しないか開けない場合、Pythonは IOError を発生させます。
  • except ブロックがそれを捕まえ、クラッシュする代わりに親切なメッセージを表示します。
TIP: try ブロックはできるだけ小さく — 失敗する可能性があるコードだけを含め、関連しないロジックは含めないでください。

複数の例外タイプの処理

複数の except ブロックを使い、異なる例外タイプを個別に処理できます:

try:
    # 例外を発生させるかもしれないコード
except TypeError:
    # 型エラーの処理
except ValueError:
    # 値エラーの処理
except:
    # その他すべての例外の処理

最後の裸の except未処理のすべての例外を捕まえますが、予期しないバグを隠してしまう可能性があるため慎重に使いましょう。

自分で例外を発生させる

プログラム中で問題があったことを知らせる必要がある場合、たとえPythonが通常エラーと見なさない場合でも、raise 文で例外を発生させることができます。

例:

def divide(a, b):
    if b == 0:
        raise ValueError("2番目の引数は0にできません")
    return a / b

print(divide(10, 2))  # 5.0
print(divide(10, 0))  # ValueError: 2番目の引数は0にできません

これにより、明確なエラーメッセージを定義し、不正なデータがあった場合に処理を停止できます。

finally ブロック

finally ブロックには、例外が発生したかどうかにかかわらず必ず実行されるコードを定義します。 主にファイルやデータベース接続などのリソースを解放するのに使われます。

例:

try:
    file = open("file.txt", "r")
    content = file.read()
    print(content)
finally:
    file.close()

ファイル読み込み中にエラーが起きても、finally ブロックがファイルを閉じることを保証します。

重要!: ファイルは必ず finally ブロックで閉じるか、あるいは "with" 文を使ってリソースリークを防ぎましょう。


理解できたでしょうか — ここで エラーハンドリング レッスンに追加できるセクションを紹介します。「すべての例外をtry/exceptで捕まえる」ことがなぜ悪いのか、適切に例外を捕まえるべき理由を説明しています。


なぜ意味もなくすべての例外を捕まえるべきでないのか

初心者によくある間違いは、巨大なコードの塊を1つの try/except で囲み、すべての例外を捕まえること、あるいはエラータイプを指定しない裸の except: を使うことです。

悪い例:

try:
    # 関連しない大量のコード
except:
    pass  # すべてのエラーを無視

これが危険な理由:

  • バグを隠す: 本当のミスは無視され、発見しにくくなる。
  • 原因を覆い隠す: 何が失敗したのかの情報が失われる。
  • 予期しない動作を引き起こす: プログラムが無効な状態で動き続ける。

広範囲の例外処理が許されるケース

すべての例外を捕まえる (except Exception:) は稀で意図的な場合に限られます。 例としては:

  • プログラムのトップレベルでエラーをログに残し、クラッシュを防ぐ場合。
  • 常に動作を続けなければならないサービスのフェイルセーフループ(ただしエラーはログ・報告する)。
  • 一時的なデバッグ目的でとにかく何か問題があるかを素早く確認したいとき(短期的な手段として)。

ベストプラクティス

  • 具体的に:想定し、処理方法のわかっている例外だけを捕まえる。
  • try ブロックは小さく:失敗する可能性のあるコードだけを囲み、関数全体を囲わない。
  • 例外は必ずログを残すか適切に処理:単に pass して無視しない。

これにより、コードのデバッグが容易になり、安全で予測可能な動作が保証されます。


まとめ

エラーハンドリングはPythonプログラミングの基本要素です:

  • 予期しないクラッシュを防ぎます。
  • 問題に対して優雅に対処可能にします。
  • コードをより堅牢で信頼性が高く、安全なものにします。

例外の扱い方、カスタムエラーの発生方法、finally の使い方をマスターすれば、現実世界に対応したより良いプログラムを書くことができます。