Python初心者必見!例外処理try-exceptを使いこなしてバグ知らずのコードへ

2025年4月27日日曜日

Python

この記事では、Pythonのtry-except構文、つまり例外処理(エラー処理)の基本から応用までを、どこよりも分かりやすく解説します! 

プログラミング学習中の皆さん、予期せぬエラーでプログラムが止まって頭を抱えた経験、ありますよね? 大丈夫、この記事を読めば、そんな悩みとはおさらばできます。

この記事で学べること

  • try exceptの基本的な仕組みがわかる
  • エラーの種類に応じて処理を分ける方法がわかる
  • ファイル操作やユーザー入力など、実際の場面での使い方がわかる
  • エラー処理を書く上でのコツや注意点がわかる

エラーを恐れずに、もっと自由にPythonプログラミングを楽しめるようになりましょう!

Pythonのtry-exceptとは?エラー処理の守護神

Pythonのtry exceptは、プログラム実行中に発生するかもしれないエラー(専門用語で「例外」といいます)に対処するための仕組みです。

プログラムを書いていると、ファイルを読み込もうとしたらそのファイルが存在しなかったり、数字で割り算しようとしたら割る数がゼロだったり、色々な予期せぬ事態が起こりえます。

もし、そういった事態への備えがないと、プログラムはエラーメッセージを表示して途中で止まってしまいます。ユーザーにとっては不親切ですし、場合によっては作業中のデータが失われるかもしれません。

そこで登場するのがtry except! こいつがあれば、エラーが起きそうな処理を「試してみて(try)」、もしエラーが起きたら「こう対処する(except)」という流れを作れるんです。まるでプログラムのエラー処理における守護神みたいな存在ですね!

なぜtry-exceptを使う必要があるのか?

try exceptを使う一番の理由は、プログラムを安定して動かすためです。

予期せぬエラーが発生しても、プログラムがいきなり停止するのを防げます。これによって、ユーザーは安心してプログラムを使い続けられますし、開発者も「エラーで止まっちゃった!」という報告に頭を悩ませる回数が減るでしょう。

他にも、以下のような良い点があります。

  • エラーの原因特定が楽になる
    どこでどんなエラーが起きているかを把握しやすくなります。
  • ユーザーに優しい
    意味不明なエラーメッセージではなく、「ファイルが見つかりません」や「数値を入力してください」のような分かりやすいメッセージを表示できます。
  • 後処理を確実に実行できる
    例えばファイルを開いた後、エラーがあってもなくてもファイルを確実に閉じる、といった処理を保証できます。(これは後述する`finally`を使います)

もしtry exceptを使わなかったら… 想像してみてください。

ちょっとした入力ミスでプログラムが落ちる、大事な処理の途中でデータが壊れる… そんな不安定なプログラム、嫌ですよね? try exceptは、そんな悲劇を防ぐための必須テクニックなんです。

try-exceptの基本的な書き方入門

さて、try exceptの基本的な使い方を見ていきましょう。
基本形はとてもシンプルで、`try`と`except`という二つのブロックから成り立ちます。

try:
    # エラーが起きるかもしれない処理
    処理内容1
    処理内容2
except:
    # tryブロック内でエラーが起きた場合に実行される処理
    エラー時の処理内容

「try:」の下には、エラーが発生する可能性のあるコードを書きます。

「except:」の下には、もし`try`ブロックの中でエラーが発生した場合に、実行したいコードを書きます。もしエラーが発生しなければ、`except`ブロックは無視されます。

tryブロック 試したい処理を書く場所

`try`ブロックは、いわば「挑戦コーナー」です。

ここに、エラーを出すかもしれないけど、実行してみたい処理を書きます。例えば、ユーザーが入力した数値を割り算に使う場合、ゼロで割ってしまう可能性がありますよね。そんな処理を`try`の中に書きます。

# 例:ゼロで割る可能性がある処理
try:
    num = 10
    divisor = 0 # わざとゼロを入れてみる
    result = num / divisor # ここでエラーが出るかも!
    print(f"割り算の結果: {result}") # エラーが出なければ実行される
except:
    print("おっと!割り算で何か問題が起きたようです。")

上の例だと、`divisor`が0なので、`result = num / divisor`の行で`ZeroDivisionError`というエラーが発生します。そのため、`print(f"割り算の結果: {result}")`は実行されずに、`except`ブロックの処理に移ります。

exceptブロック エラー発生時の処理

`except`ブロックは、「もしもの時の備え」です。

`try`ブロックでエラーが発生した場合に、プログラムが停止する代わりに実行される処理を書く場所になります。エラーが起きたことをユーザーに知らせたり、エラーログを記録したり、代替の処理を行ったりします。

先ほどの例では、ゼロ除算エラーが発生したので、`except`ブロック内の`print("おっと!割り算で何か問題が起きたようです。")`が実行されました。`except`のおかげでプログラムが途中で止まらずに済みましたね

# 実行結果
おっと!割り算で何か問題が起きたようです。

ただ、どんなエラーでも同じメッセージが表示されるのは少し不親切かもしれません。次は、エラーの種類に応じて処理を変える方法を見ていきましょう。

elseブロック エラーが起きなかった時の処理

`try except`には、`else`というブロックを追加することもできます。

`else`ブロックは、`try`ブロック内の処理がエラーなく、すべて正常に完了した場合にのみ実行されます。エラーが発生した場合は実行されません。

「エラーがなかった時だけ、この処理をしたい」という場合に便利です。

try:
    num = 10
    divisor = 2 # 今度はエラーが出ないようにする
    result = num / divisor
except:
    print("割り算でエラーが発生しました。")
else:
    # エラーが起きなかったので、このブロックが実行される
    print(f"割り算は成功しました! 結果: {result}")
# 実行結果
割り算は成功しました! 結果: 5.0

エラーが発生しなかったので、`except`ブロックはスキップされ、`else`ブロックが実行されました。

finallyブロック 必ず実行される処理

さらに、`finally`というブロックも追加できます。

`finally`ブロックは、`try`ブロックでエラーが発生しようがしまいが、最後に必ず実行される処理を書く場所です。

よく使われるのが、ファイルを開いた後に必ず閉じる処理や、ネットワーク接続を切断する処理など、「後片付け」が必要な場面です。

try:
    f = open("my_file.txt", "w") # 書き込みモードでファイルを開く (存在しなければ新規作成)
    f.write("try exceptのテスト\n")
    # わざとエラーを起こしてみる (数値 / 文字列)
    # result = 10 / "a"
except TypeError: # 型エラーをキャッチ
    print("型に関するエラーが発生しました。")
# except FileNotFoundError: # ファイルが見つからないエラー
#    print("ファイルが見つかりませんでした。")
else:
    print("ファイルへの書き込みが成功しました。")
finally:
    # エラーがあってもなくても、ファイルは必ず閉じる
    f.close()
    print("ファイルのクローズ処理を実行しました。")

この例では、`finally`ブロックで`f.close()`を実行しているので、途中で`TypeError`が発生したとしても(コメントアウトを外した場合)、あるいは正常に処理が終わったとしても、ファイルは確実に閉じられます。

リソースの解放漏れを防ぐために非常に役立ちます

try-exceptで特定のエラーをキャッチする方法

これまでの例では、`except:`とだけ書いて、どんな種類のエラーでもキャッチしていました。しかし、実際にはエラーの種類に応じて処理を変えたい場合が多いです。

例えば、「ファイルが見つからないエラー」と「ゼロで割ったエラー」では、ユーザーに表示したいメッセージも、プログラム側で行うべき対処も異なるはずです。

特定のエラーだけをキャッチするには、`except`の後ろにエラーの種類(例外クラス名)を指定します。

try:
    num_str = input("数字を入力してください: ")
    num_int = int(num_str) # 文字列を整数に変換しようとする
    result = 100 / num_int # 割り算
    print(f"100を{num_int}で割った結果は {result} です。")

except ValueError:
    # int()での変換に失敗した場合 (数字以外が入力された)
    print("エラー: 数字を入力してくださいね!")

except ZeroDivisionError:
    # ゼロで割ろうとした場合
    print("エラー: 0で割ることはできませんよ!")

except Exception as e:
    # 上記以外の予期せぬエラーが発生した場合
    print(f"予期せぬエラーが発生しました: {e}")

このコードでは、

  • ユーザーが数字以外を入力 → `ValueError`が発生 → 「エラー: 数字を入力してくださいね!」と表示
  • ユーザーが「0」を入力 → `ZeroDivisionError`が発生 → 「エラー: 0で割ることはできませんよ!」と表示
  • それ以外のエラー(もしあれば)→ `Exception`がキャッチ → エラー内容を表示

というように、エラーの種類に応じて異なる処理を実行できます。`Exception`は多くのエラーの親玉のようなものなので、最後に書いておくと、想定外のエラーもキャッチできて安心です。

複数のエラーをまとめてキャッチする

もし、複数の異なるエラーに対して、同じ処理を行いたい場合は、例外クラス名をタプル(丸括弧で囲んだもの)でまとめて指定できます。

try:
    # 何かしらの処理...
    # 例えば、ファイル読み込みと数値計算が混在する処理
    file_path = input("ファイルパスを入力: ")
    with open(file_path, 'r') as f:
        content = f.read()
        num = int(content.strip()) # ファイル内容を数値に
        result = 100 / num
        print(f"計算結果: {result}")

except (FileNotFoundError, ValueError, ZeroDivisionError) as e:
    # ファイルが見つからない or 数値変換できない or ゼロ除算 のどれか
    print(f"処理中にエラーが発生しました: {e}")
    print("ファイルパスやファイル内容を確認してください。")

この例では、`FileNotFoundError`(ファイルが見つからない)、`ValueError`(数値に変換できない)、`ZeroDivisionError`(ゼロ除算)のいずれかが発生した場合に、同じ`except`ブロックが実行されます。コードがスッキリしますね。

例外オブジェクトを使ってエラー詳細を取得する

エラーが発生した際、具体的にどんなエラーメッセージが出ているのかを知りたい場合があります。そんな時は、`except`文で`as`を使ってエラー情報(例外オブジェクト)を変数に格納できます。

try:
    nums = [1, 2, 3]
    print(nums[5]) # わざと範囲外のインデックスを指定

except IndexError as error_info: # IndexErrorが発生したら、その情報をerror_info変数へ
    print(f"エラーの種類: {type(error_info)}")
    print(f"エラーメッセージ: {error_info}")
    print("リストの範囲を超えたアクセスがありました。インデックスを確認してください。")

# 実行結果
エラーの種類: <class 'IndexError'>
エラーメッセージ: list index out of range
リストの範囲を超えたアクセスがありました。インデックスを確認してください。

このように`as error_info`(変数名は何でもOK)と書くことで、`error_info`という変数の中にエラーの詳細情報が格納されます。これを`print()`で表示したり、ログファイルに記録したりすることで、デバッグが格段にしやすくなります。

try-exceptの実践的な使い方

理屈は分かったけど、実際にどんな場面で使うの? と思いますよね。
ここでは、よくあるシチュエーションでのtry exceptの活用例を見てみましょう。

ファイル操作におけるtry except

ファイル操作はエラーが起きやすい代表例です。指定したファイルが存在しない(`FileNotFoundError`)、読み書きの権限がない(`PermissionError`)など、様々な問題が考えられます。
`try except`と、後片付けのための`finally`を組み合わせるのが定番です。

file_path = "data.txt"
file = None # finallyで使うために、先に変数を定義しておく

try:
    # ファイルを読み込みモードで開く
    file = open(file_path, "r", encoding="utf-8")
    content = file.read()
    print("ファイルの内容:")
    print(content)

except FileNotFoundError:
    print(f"エラー: ファイル'{file_path}'が見つかりません。")
except Exception as e:
    print(f"ファイル処理中に予期せぬエラーが発生しました: {e}")
finally:
    # ファイルオブジェクトが生成されていたら(=openが成功していたら)閉じる
    if file:
        file.close()
        print("ファイルをクローズしました。")

このコードでは、まず`open()`を`try`ブロックで行い、ファイルが見つからない場合に`FileNotFoundError`をキャッチします。それ以外の予期せぬエラーも`Exception`でキャッチしています。

そして、`finally`ブロックで、`file`変数がNoneでない(つまりファイルが開かれている)ことを確認してから`file.close()`を実行しています。これにより、ファイルが開きっぱなしになるのを確実に防げます。

(ちなみに、`with open(...) as ...:`構文を使うと、`finally`で`close()`を書かなくても自動で閉じてくれるので、そちらの方がより現代的で推奨される書き方です!)

ユーザー入力の数値変換におけるtry except

ユーザーからの入力を受け付けて、それを数値として処理したい場合も`try except`が活躍します。
ユーザーが数字以外を入力すると`int()`や`float()`は`ValueError`を発生させるため、これをキャッチして対処します。

while True: # 正しい入力があるまで繰り返す
    try:
        age_str = input("あなたの年齢を入力してください: ")
        age_int = int(age_str) # 文字列を整数に変換

        if age_int < 0:
             print("年齢は0以上で入力してくださいね。")
        else:
             print(f"なるほど、あなたは{age_int}歳なのですね!")
             break # 正しい入力が得られたのでループを抜ける

    except ValueError:
        print("エラー! 数字で入力してください。")

この例では、`int()`での変換を`try`ブロックに入れています。もしユーザーが「abc」のような文字列を入力すると`ValueError`が発生し、`except`ブロックのメッセージが表示されます。

`while True:`と`break`を組み合わせることで、ユーザーが正しい数値を入力するまで、繰り返し入力を促すことができます。ユーザーに優しいプログラムですね。

try-exceptを使う上での注意点

try exceptは強力ですが、使い方を間違えると逆に分かりにくいコードになってしまうこともあります。ここでは、いくつか注意点と、より良いコードを書くためのコツを紹介しますね。

  • 裸のexceptは避ける (`except:`だけの形)
    どんなエラーでもキャッチしてしまうため、想定外のエラー(例えばプログラムの根本的なバグ)まで握りつぶしてしまい、問題の発見が遅れる可能性があります。できるだけ具体的な例外クラスを指定しましょう。最低でも`except Exception:`のように書くのがおすすめです。
  • tryブロックは短く、具体的に
    `try`ブロックの中には、エラーが発生する可能性のある処理だけを、できるだけ最小限の範囲で記述するように心がけましょう。範囲が広すぎると、どこでエラーが発生したのか分かりにくくなります。
  • エラー処理を無視しない
    `except`ブロックに`pass`だけを書いてエラーを完全に無視するのは、よほどの理由がない限り避けましょう。なぜエラーが起きたのか、後で追跡できなくなってしまいます。エラーログを残すか、少なくとも開発中はエラー内容を表示するようにしましょう。
  • 正常系の処理は`else`ブロックへ
    エラーが起きなかった場合に実行したい処理は、`try`ブロックに長く書くよりも、`else`ブロックに書く方が、コードの意図が明確になります。
  • 適切なエラーメッセージ
    ユーザーに見せるエラーメッセージは、何が問題だったのか、次にどうすればいいのかが分かるように、具体的で分かりやすい言葉を選びましょう。

これらの点を意識するだけで、ぐっと読みやすく、そして問題を発見しやすいエラー処理が書けるようになりますよ。

【まとめ】Pythonのtry-exceptを使いこなしてエラーに強いコードを書こう

今回は、Pythonのエラー処理の基本である`try except`構文について、基本的な使い方から実践的な活用例、注意点までを見てきました。もう一度ポイントをおさらいしましょう。

  • `try`ブロックにエラーが起きそうな処理を書く
  • `except`ブロックにエラー発生時の処理を書く(エラーの種類を指定するのが基本!
  • `else`ブロックはエラーが起きなかった時に実行される
  • `finally`ブロックはエラーの有無に関わらず最後に必ず実行される(後片付けに便利)
  • ファイル操作やユーザー入力処理など、エラーが予測される場面で積極的に活用する
  • 裸の`except:`は避け、`try`ブロックは短く保つ

最初は少し難しく感じるかもしれませんが、実際にコードを書いて動かしてみるのが一番の近道です! ぜひ、ご自身のプログラムにtry exceptを組み込んで、エラーに負けない、たくましいコードを書いてみてください。

エラーは怖いものではなく、プログラムをより良くするためのヒントを与えてくれる存在です。try exceptを味方につけて、Pythonプログラミングをもっと楽しんでいきましょう!

【関連記事】 「Pythonとは?」に答える最初の一歩

このブログを検索

  • ()

自己紹介

自分の写真
リモートワークでエンジニア兼Webディレクターとして活動しています。プログラミングやAIなど、日々の業務や学びの中で得た知識や気づきをわかりやすく発信し、これからITスキルを身につけたい人にも役立つ情報をお届けします。 note → https://note.com/yurufuri X → https://x.com/mnao111

QooQ