はじめに
Pythonのエラーハンドリングで try ~ except Exception as e
のような処理も書けますが、サブクラスを使用する事でより細かなエラーハンドリングをすることができます。本記事ではこれらを使用したエラーハンドリングについて簡単な例を実装していきます。
サブクラスを使用するメリット
- エラーの種類ごとに異なる処理が可能
- 各エラーに対してエラーメッセージをより具体的に設定できる
- エラーの階層構造を作れる
具体例
デフォルトの Exception と サブクラス を使用したものを1つずつ見てみます。
例1:Exception クラス
def connect_database():
try:
# データベース接続の処理
connection = db.connect()
except Exception as e:
# すべてのエラーを一括で処理
print(f"エラーが発生しました: {e}")
return None
上記の場合、エラーメッセージ(= e
)から何が原因なのかを読み取ることはできますが、エラーの種類ごとに異なる処理を書くことができません。
例えば「接続エラーの場合は再接続を試みる」「タイムアウトの場合は少し待ってから再接続する」といった処理の振り分けができません。
例2:サブクラス
def connect_database():
try:
# データベース接続の処理
connection = db.connect()
except ConnectionError as e:
# 接続エラーの場合の処理
print(f"接続エラー: {e}")
# 再接続を試みる
return retry_connection()
except TimeoutError as e:
# タイムアウトの場合の処理
print(f"タイムアウト: {e}")
# 時間をおいて再接続
return wait_and_retry()
except Exception as e:
# 想定外のエラーの処理
print(f"予期せぬエラーが発生しました: {e}")
return None
サブクラスを使用するとエラーの種類によって異なる対処が可能です。
例えば、接続エラーの場合はすぐに再接続を試み、タイムアウトの場合は少し時間をおいてから再試行するなど、状況に応じた適切な処理を実装できます。
サブクラスを使用した処理の実行例
例としてファイル読み込みの処理をクラスとして定義し、サブクラスを使用した処理を実行していきます。
def read_file(filepath):
# ファイルの読み込みを行う関数
with open(filepath, 'r') as f:
return f.read()
def try_read(filepath):
try:
# ファイルを読み込む
content = read_file(filepath)
print(f"ファイルの内容: {content}")
except FileNotFoundError as e:
# ファイルが存在しない場合の処理
print(f"ファイルが見つかりません: {e}")
except TypeError as e:
# ファイルパスの型が不正な場合の処理
print(f"ファイルパスの型が不正です: {e}")
except Exception as e:
# その他の予期せぬエラーの処理
print(f"予期せぬエラー: {e}")
# test.txtファイルは事前に作成されてる想定
print("1. 正常な実行:")
try_read("test.txt")
print("\n2. 存在しないファイルの読み込み:")
try_read("not_exist.txt")
print("\n3. 不正な型のファイルパス:")
try_read(None)
read_file, try_read について
-
read_file
関数について-
read_file
メソッド:与えられたファイルパスのファイルを読み込む- ファイルが存在する場合:内容を返す
- ファイルが存在しない場合:FileNotFoundErrorを発生
- パスの型が不正な場合:TypeErrorを発生
-
-
try_read
関数について- read_file関数のインスタンスを作成
- ファイル読み込みを試みて、発生するエラーの種類に応じて処理を分岐
- エラーメッセージを出力
スクリプトを実行
次のコマンドで処理を実行してみます。
python .\index.py
スクリプトを実行する前に、カレントディレクトリに test.txt
が準備されている事を想定しています。
本記事では Hello, World!
と書き込んだものを使用しています。
1. 正常な実行:
ファイルの内容: Hello, World!
2. 存在しないファイルの読み込み:
ファイルが見つかりません: [Errno 2] No such file or directory: 'not_exist.txt'
3. 不正な型のファイルパス:
ファイルパスの型が不正です: expected str, bytes or os.PathLike object, not NoneType
各ケースの動作を詳しく見てみましょう:
-
正常系(test.txt)
- 実在するファイルなので読み込み成功
- ファイルの内容(
Hello, World!
)が表示される
-
存在しないファイル(not_exist.txt)
- ファイルが存在しないので
FileNotFoundError
が発生 - エラーをキャッチして適切なメッセージ(
ファイルが見つかりません
)を表示
- ファイルが存在しないので
-
不正な型のパス(None)
- 文字列以外のパスなので
TypeError
が発生 - エラーをキャッチして適切なメッセージ(
ファイルパスの型が不正です
)を表示
- 文字列以外のパスなので
このように、エラーの種類に応じて異なるメッセージを表示し、適切な処理を行うことができます。
参考
https://docs.python.org/ja/3/library/exceptions.html#FileNotFoundError
https://docs.python.org/ja/3/library/exceptions.html#TypeError
https://docs.python.org/ja/3/library/exceptions.html#Exception