【Python try】例外処理の基礎と実務での使い方を初心者向けにわかりやすく解説

はじめに

エラーが発生したときにプログラムが強制終了してしまうと、作業の中断やシステムの停止につながる場合があります。
Pythonでは、try 文という仕組みを使うことでエラーを適切に処理し、プログラムの異常終了を防ぎながら動作を継続させることができます。

初心者の方は「エラーが出るとプログラムがどう止まるのか」「どうやってエラーを回避すればよいのか」といった点がわかりにくいかもしれません。
そこで、本記事ではPythonにおけるtry文の書き方や考え方をわかりやすく解説します。
実務でも活用できるよう、ファイル操作やAPI通信など、具体的なコード例もあわせて紹介していきます。

この記事を読むとわかること

  • Pythonのtry文を使った例外処理の仕組み
  • except, else, finally の使い方と組み合わせ方法
  • ファイル操作やAPI通信など実務での活用シーンにおける具体例

Pythonのtryとは?

Pythonのtry文は、エラー(例外)が発生しうる処理をまとめるための構文です。
エラーが起きそうなコードをtryブロックに書いておくことで、もし実行時にエラーが発生したとしても、自動的に指定した処理(exceptブロック)が呼び出されます。

この仕組みを使うことで、プログラムの予期せぬ停止を避けることができます。
たとえば、「ファイルを開こうとしたら存在しなかった」「APIサーバーが落ちていて通信できなかった」といったケースで、適切にエラーを拾い、対処する方法を提供してくれます。

エラーというと何となく嫌なイメージがあるかもしれませんが、システム開発ではエラー発生をどう防ぐかよりも、どう処理すべきかを考えることが大事です。
try文を使いこなせるようになると、想定外の事態に柔軟に対応できるプログラムを書くことが可能になります。

Pythonの例外処理を行うメリット

例外処理を行う最大のメリットは、「プログラムの異常終了を防ぐ」ことです。
たとえば、大きなファイルを扱うプログラムであっても、ファイルがなかったり読み取り専用でエラーになったりするケースは想定しやすいです。
こうした場合にtry文を使っておけば、エラーをキャッチして条件分岐的に処理を変更できるので、ユーザーにわかりやすいメッセージを表示したり、ほかの動作を継続したりできます。

また、例外処理を明確に記述しておくことで、コードの可読性や保守性も向上します。
予想可能なエラーが明確に区分されていると、他の開発者がコードを読んだときに「こういうエラーはここで処理するんだな」と理解しやすくなります。
結果として、バグ修正や機能追加などの際もスムーズに対応できるようになるでしょう。

例外処理は大量のデータを扱う環境や、外部のAPIとやり取りするサービス開発でも重宝されます。
予測できないエラーが起こっても、プログラムを止めずに柔軟に対応できるためです。

基本的なtry-except構文

Pythonで例外処理を行うときは、以下のような構文をよく使います。

try:
    # エラーが発生するかもしれないコード
    result = 10 / 0
    print(result)
except ZeroDivisionError:
    print("0で割ることはできません。")

上記の例で、10 / 0 はゼロ除算のエラーを引き起こします。
しかし、try ブロック内に書いておくことで、実行時に ZeroDivisionError が発生したら、自動的に except ZeroDivisionError: で定義したブロックが呼ばれます。
その結果、「0で割ることはできません。」というメッセージが表示され、プログラム自体は停止せずに先へ進みます。

複数のexceptを使う

一つの処理で複数のエラー発生パターンが考えられる場合は、複数の except を並べることも可能です。

try:
    # 複数のエラー可能性があるコード
    data_list = [1, 2, 3]
    index = 5
    value = data_list[index]  # IndexErrorが起きるかもしれない
    result = value / 0        # ZeroDivisionErrorが起きるかもしれない
except IndexError:
    print("指定したインデックスは範囲外です。")
except ZeroDivisionError:
    print("0で割り算はできません。")

このコードでは、リストの範囲外をアクセスすると IndexError、ゼロ除算すると ZeroDivisionError が発生します。
いずれのエラーが起きた場合でも、対応する except ブロックに処理が移るため、プログラムが強制終了せずに済みます。

finallyの使い方

例外が起きても起きなくても、最後に必ず実行したいコードを記述したい場合は、finally を使います。

try:
    f = open("sample.txt", "r")
    content = f.read()
    print(content)
except FileNotFoundError:
    print("ファイルが見つかりませんでした。")
finally:
    print("処理が終わりました。リソースを解放します。")
    # f は定義済みかどうか確かめながらクローズする方法もあります
    # 例)if 'f' in locals(): f.close()

finally はエラーの有無に関係なく、最後に必ず呼び出されます。
リソースの解放やログ出力など、後処理が必要な場合に非常に有用です。
ファイルアクセスやデータベース操作などではよく使われる構文の一つです。

else節の使いどころ

Pythonの例外処理では、tryexcept のほかに else を組み合わせることができます。
else ブロックは、「例外が発生しなかった場合」に実行されるコードをまとめたいときに便利です。

try:
    number = int(input("数字を入力してください: "))
except ValueError:
    print("数字を正しく入力してください。")
else:
    # 例外が起きなかった場合にのみ実行
    print(f"入力された数字は {number} ですね。")

このように書くと、入力値が整数に変換できなかった場合は except ValueError: が呼ばれ、正常に変換できた場合のみ else ブロックの処理が走ります。
不必要に if 文を増やさず、例外がなかったときの処理をスッキリ分離できるのが利点です。

実務シーンでの活用例:ファイル操作

ファイル操作は、実務でも非常によく出てくる場面です。
「ファイルを開こうとしたが見つからない」「読み込み専用なのに書き込み操作をしようとした」というケースは、割と日常的に起こるものです。
こうしたとき、try文であらかじめ例外処理を入れておくと、プログラムが落ちずに済みます。

ファイルの読み込みでのtry活用

以下のサンプルでは、テキストファイルが存在しない場合に適切なエラー処理を行い、プログラムを終了させないようにします。

try:
    with open("config.txt", "r") as f:
        config_data = f.read()
        print("設定ファイルの内容を読み込みました。")
except FileNotFoundError:
    print("設定ファイルが見つかりません。標準設定を使用します。")
except PermissionError:
    print("ファイルにアクセスする権限がありません。")
else:
    print("設定ファイルが存在しました。内容:", config_data)
finally:
    print("ファイル読み込みを試みました。")

ファイルが存在しない場合やアクセス権がない場合に、独自のメッセージを表示しつつプログラムの続行を可能にしています。
with open(...) as f: 構文を使うと、自動的にファイルがクローズされるので、リソース管理の手間を減らすことができます。

ファイル書き込みでのtry活用

ファイル書き込みでも例外処理があると安心です。
特に、読み込みと書き込みでは想定されるエラーの内容が異なることがあります。

data_to_save = "ユーザーが入力したデータ"

try:
    with open("output.txt", "w") as f:
        f.write(data_to_save)
        print("ファイルへの書き込みに成功しました。")
except PermissionError:
    print("ファイルへの書き込み権限がありません。")
except OSError:
    print("ファイル書き込み時に何らかのOSエラーが発生しました。")
else:
    print("書き込み完了後の追加処理を実行します。")
finally:
    print("ファイル書き込み手続きが完了しました。")

ファイル書き込みの途中でディスクがいっぱいになっていたり、権限がなかったりすることもありえます。
そのような場合でも、try文を使うことで、ただちにエラーを捕捉してユーザーに伝えたり、別のフォルダに退避したりといった柔軟な処理ができるようになります。

実務シーンでの活用例:API通信

アプリケーションで外部のAPIを呼び出す場面も多いでしょう。
ここでは、通信エラーやネットワークエラーが起こる可能性が高くなります。
Pythonでは、よく使われるHTTP通信ライブラリとして requests を利用することがあります。

import requests

try:
    response = requests.get("https://example.com/api/data")
    # ステータスコードによっては例外を発生させる
    response.raise_for_status()
    data = response.json()
    print("取得したデータ:", data)
except requests.exceptions.HTTPError:
    print("HTTPエラーが発生しました。")
except requests.exceptions.ConnectionError:
    print("サーバーに接続できませんでした。")
except requests.exceptions.Timeout:
    print("タイムアウトが発生しました。")
except requests.exceptions.RequestException:
    print("その他のリクエストエラーが発生しました。")
else:
    print("API通信に成功しました。")
finally:
    print("API通信の処理が終了しました。")

ここでは requests.get の呼び出しや raise_for_status() でエラーが起きるかもしれません。
ネットワークが不安定だったり、サーバーの応答が遅延したりすると、さまざまな例外に対処しなければなりません。
そのため、try-except構文が役立ちます。
外部サービスへの通信はシステムの安定性に大きく影響するため、エラー時の挙動を明確にしておくと安心です。

実務シーンでの活用例:ユーザー入力の検証

ユーザー入力は想定外の値が入りやすいという特徴があります。
数値を期待しているのに文字列が入力されたり、メールアドレスに何でもない文字列が渡されたりするケースはよくあります。

def get_user_age():
    try:
        age_str = input("年齢を入力してください: ")
        age_int = int(age_str)
        if age_int < 0:
            raise ValueError("年齢は正の値であるべきです。")
        return age_int
    except ValueError as e:
        print(f"入力に問題があります: {e}")
        return None

user_age = get_user_age()
if user_age is not None:
    print(f"入力された年齢: {user_age}")
else:
    print("正しい年齢が入力されませんでした。")

ここでは、int 関数による変換エラー、もしくは独自の条件(年齢がマイナスであるなど)で ValueError を発生させています。
どちらも except ValueError: でまとめて処理し、エラーが起きた旨をユーザーに伝えます。
こうしたアプローチにより、想定外の入力に対してプログラムが落ちず、適切なエラーメッセージを返すことができます。

try-except-else-finallyを組み合わせた活用パターン

ここまで、Pythonの例外処理を構成する要素である try, except, else, finally について解説してきました。
これらを組み合わせると、正常処理・異常処理・エラーがなかった場合の処理・後始末という流れが明確になります。

def process_data(data):
    if not data:
        raise ValueError("データが空です。")
    return [item * 2 for item in data]

try:
    data_list = [1, 2, 3]
    result = process_data(data_list)
except ValueError as e:
    print(f"エラーが発生しました: {e}")
else:
    print("データ処理は成功です。結果:", result)
finally:
    print("処理を終了します。メモリ使用量などをチェックしてクリーンアップを行う想定です。")

このように書くと、次のような流れがはっきり可視化できます。

  1. try:エラーが起きそうな処理を試す
  2. except:エラーが起きたら、何が原因かを表示して終了処理を行う
  3. else:エラーが起きなかった場合にだけ、成功後の処理(メッセージ表示や追加計算など)を実行
  4. finally:エラーの有無にかかわらず、最後に必ずクリーンアップなどを実行

こうした構成にしておくと、実務における保守管理やトラブルシュートがとてもやりやすくなります。
どのタイミングでどんな処理が走っているかを他の開発者も理解しやすいからです。

実務で複雑な処理が絡む場合こそ、try-except-else-finallyをセットで考えておくと、予期せぬエラーへの対処と正常時のフローを明確に分離できます。

ユニットテストでの例外処理テスト

ソフトウェアの品質を高めるために、ユニットテストを書いてエラー処理が正しく動くか確認する方法があります。
例外が正しく発生するか、または発生しないかをテストすることで、想定通りの挙動を担保しやすくなります。

# 簡単な例として、unittestを使ったサンプル
import unittest

def divide(a, b):
    return a / b

class TestDivideFunction(unittest.TestCase):
    def test_divide_success(self):
        self.assertEqual(divide(10, 2), 5)

    def test_divide_zero(self):
        with self.assertRaises(ZeroDivisionError):
            divide(10, 0)

if __name__ == "__main__":
    unittest.main()

ここで test_divide_zero では、ZeroDivisionError が発生することを期待してテストを行っています。
もし例外が発生しなければテスト失敗となり、「想定外の動作をしている」と判断できます。
このように、自分で書いた例外処理の動きをテストで検証できると、エラー処理に対する信頼性が高まり、現場で安心してプログラムを運用できます。

まとめ

Pythonのtry文を使うと、エラー(例外)が起きてもプログラムを止めずに適切な処理を行うことが可能になります。
except で複数のエラーをそれぞれハンドリングできるだけでなく、elsefinally を活用することで、正常時とエラー時のフローをわかりやすく区分できます。

実務では、ファイル操作・API通信・ユーザー入力などでエラー処理が頻繁に登場します。
適切な例外処理を入れておけば、もしものときにシステムが落ちてしまうリスクを減らし、ユーザーにわかりやすいフィードバックを返すことができます。
どんなシステムでもエラーをゼロにするのは難しいですが、エラーが発生したときの被害を最小限に抑え、素早く復帰させるのが例外処理の大きな役目です。

初心者の方は、まずは try-except で基本的な使い方を覚え、慣れてきたら elsefinally を加えてみてください。
エラー処理を丁寧に書けるようになると、保守しやすく、安全性の高いコードを書けるようになります。
これを機に、ぜひご自身のプロジェクトでも Python の try文を活用してみてください。

Pythonをマスターしよう

この記事で学んだPythonの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。