はじめに
この実験(Lab)では、try...except ステートメントを使用して、Python で例外を効果的に処理する方法を学びます。ValueError のような特定の例外を捕捉する方法、複数の例外タイプを処理する方法、そしてプログラムの流れをより細かく制御するための else ブロックと finally ブロックの使用法を探ります。また、コード内で特定のエラー条件を示すためにカスタム例外を発生させる方法についても学習します。実践的な演習を通じて、堅牢でエラー耐性のある Python プログラムを作成するための実用的な経験を積むことができます。
try except で ValueError を処理する
このステップでは、try...except ステートメントを使用して ValueError を処理する方法を学びます。ValueError は、関数が適切な型の引数を受け取ったものの、不適切な値であった場合に発生します。一般的な例としては、int() 関数を使用して数ではない文字列を整数に変換しようとする場合が挙げられます。
ここでは、ユーザーに整数を入力するように促す Python スクリプトを作成します。入力が有効な整数でない場合、ValueError を捕捉し、ユーザーフレンドリーなメッセージを表示します。
左側の WebIDE ファイルエクスプローラーで、~/project ディレクトリにある handle_value_error.py ファイルを見つけて開いてください。次に、以下のコードをファイルに追加します。
while True:
try:
x = int(input('Please enter an integer: '))
print(f'You entered: {x}')
break
except ValueError:
print('That was not a valid integer. Please try again.')
ファイルを保存します。
次に、統合ターミナルを開き、python コマンドを使用してスクリプトを実行します。
python ~/project/handle_value_error.py
スクリプトは整数を入力するように求めます。まず、hello のような整数ではない値を入力して、エラー処理が機能していることを確認してください。次に、123 のような有効な整数を入力して、正常な実行パスを確認します。
出力例:
Please enter an integer: hello
That was not a valid integer. Please try again.
Please enter an integer: 123
You entered: 123
このコードでは:
while True:ループは、有効な整数が入力されるまでプログラムが入力入力を求め続けることを保証します。tryブロックには、例外を発生させる可能性のあるコード、具体的にはint(input(...))の呼び出しが含まれています。tryブロック内でValueErrorが発生した場合、except ValueError:ブロック内のコードが実行されます。- 例外が発生しなかった場合、
print()ステートメントが実行され、breakによってループが終了します。
これにより、try...except ValueError を使用して、プログラムをクラッシュさせることなく、無効な入力を優雅に処理する方法が示されます。
複数の例外を処理する
コードブロックは、異なる種類の例外を発生させる可能性があります。Python では、複数の except 句を使用するか、単一の except 句で例外をグループ化することにより、複数の例外を処理できます。
ここでは、除算を実行するスクリプトを作成します。この操作は、入力が数値でない場合に ValueError を、除数がゼロの場合に ZeroDivisionError を発生させる可能性があります。
WebIDE でファイル ~/project/handle_multiple_exceptions.py を開き、以下のコードを追加します。このバージョンでは、エラーの種類ごとに個別の except ブロックを使用しています。
try:
numerator = int(input("Enter the numerator: "))
denominator = int(input("Enter the denominator: "))
result = numerator / denominator
print(f"Result: {result}")
except ValueError:
print("Invalid input. Please enter integers only.")
except ZeroDivisionError:
print("Error: Division by zero is not allowed.")
ファイルを保存し、ターミナルから実行します。
python ~/project/handle_multiple_exceptions.py
スクリプトを異なる入力でテストし、それぞれの例外を発生させてください。
- 整数ではない値(例:
abc)を入力する。 - 分母に
0を入力する。 - 両方に有効な整数を入力する。
ゼロ除算の出力例:
Enter the numerator: 10
Enter the denominator: 0
Error: Division by zero is not allowed.
単一の except 句で複数の例外を処理することもでき、その場合はタプルでグループ化します。これは、異なるエラーに対して同じアクションを実行する場合に便利です。
次に、~/project/handle_multiple_exceptions.py のコードを更新し、このグループ化されたアプローチを使用します。
try:
numerator = int(input("Enter the numerator: "))
denominator = int(input("Enter the denominator: "))
result = numerator / denominator
print(f"Result: {result}")
except (ValueError, ZeroDivisionError):
print("An error occurred: Invalid input or division by zero.")
ファイルを保存し、同じテストケースで再度実行して、新しい統合されたエラーメッセージを確認してください。
else 句を使用してコードを実行する
try ステートメントには、オプションの else 句を含めることができます。else ブロック内のコードは、try ブロックが例外を発生させずに完了した場合にのみ実行されます。これは、成功時に実行されるべきコードをメインの try ブロックから分離するのに役立ちます。
除算スクリプトを修正して、else ブロックを含めてみましょう。
WebIDE でファイル ~/project/try_except_else.py を開き、以下のコードを追加します。
try:
numerator = int(input("Enter the numerator: "))
denominator = int(input("Enter the denominator: "))
result = numerator / denominator
except (ValueError, ZeroDivisionError):
print("An error occurred: Invalid input or division by zero.")
else:
print("Division successful!")
print(f"Result: {result}")
ファイルを保存し、ターミナルから実行します。
python ~/project/try_except_else.py
失敗する入力と成功する入力の両方でスクリプトをテストします。
- 分母に
0を入力して例外を発生させます。 - 有効なゼロ以外の整数を入力して、
elseブロックを実行させます。
出力例:
Enter the numerator: 10
Enter the denominator: 0
An error occurred: Invalid input or division by zero.
Enter the numerator: 10
Enter the denominator: 2
Division successful!
Result: 5.0
ご覧のとおり、除算が成功した場合にのみ else ブロック内のメッセージが出力されます。例外が発生した場合、except ブロックが実行され、else ブロックはスキップされます。
finally 句でコードの実行を保証する
try ステートメントには、オプションの finally 句もあります。finally ブロック内のコードは、try ブロックで例外が発生したかどうかにかかわらず、常に実行されます。これにより、ファイルクローズやリソース解放など、すべての場合で実行されなければならないクリーンアップアクションに最適です。
除算の例に finally ブロックを追加してみましょう。
WebIDE でファイル ~/project/try_except_finally.py を開き、以下のコードを追加します。
try:
numerator = int(input("Enter the numerator: "))
denominator = int(input("Enter the denominator: "))
result = numerator / denominator
print(f"Result: {result}")
except (ValueError, ZeroDivisionError):
print("An error occurred: Invalid input or division by zero.")
finally:
print("Execution finished.")
ファイルを保存し、ターミナルから実行します。
python ~/project/try_except_finally.py
失敗する入力と成功する入力の両方でスクリプトを実行します。
- 分母に
0を入力して例外を発生させます。 - 有効なゼロ以外の整数を入力します。
出力例:
Enter the numerator: 10
Enter the denominator: 0
An error occurred: Invalid input or division by zero.
Execution finished.
Enter the numerator: 10
Enter the denominator: 2
Result: 5.0
Execution finished.
finally ブロックからのメッセージ "Execution finished." が両方のケースで出力されていることに注目してください。finally ブロックの実行は保証されるため、重要なクリーンアップコードを記述する信頼できる場所となります。
カスタム例外を発生させる
組み込みの Python 例外ではないエラー条件を通知する必要がある場合があります。これは、独自の例外を作成およびトリガーできる raise ステートメントを使用して行うことができます。これにより、アプリケーションのエラー処理をより具体的かつ説明的にすることができます。
まず、組み込み例外を raise する方法を見てみましょう。WebIDE でファイル ~/project/raise_exception.py を開き、以下のコードを追加します。
def check_positive(number):
if number <= 0:
raise ValueError("Input must be a positive number")
print(f"The number {number} is positive.")
try:
check_positive(-5)
except ValueError as e:
print(f"Caught an exception: {e}")
try:
check_positive(10)
except ValueError as e:
print(f"Caught an exception: {e}")
ファイルを保存し、ターミナルから実行します。
python ~/project/raise_exception.py
出力は次のようになります。
Caught an exception: Input must be a positive number
The number 10 is positive.
ここでは、check_positive 関数が入力が正でない場合に ValueError を発生させ、それが except ブロックによって捕捉されています。
次に、カスタム例外を定義して発生させてみましょう。カスタム例外は、組み込みの Exception クラスを継承するクラスです。
WebIDE でファイル ~/project/custom_exception.py を開き、以下のコードを追加します。
class NegativeNumberError(Exception):
"""Custom exception raised for negative numbers."""
pass
def process_positive_number(number):
if number < 0:
raise NegativeNumberError("Negative numbers are not allowed")
print(f"Processing positive number: {number}")
try:
process_positive_number(-10)
except NegativeNumberError as e:
print(f"Caught custom exception: {e}")
try:
process_positive_number(20)
except NegativeNumberError as e:
print(f"Caught custom exception: {e}")
ファイルを保存し、ターミナルから実行します。
python ~/project/custom_exception.py
出力は次のようになります。
Caught custom exception: Negative numbers are not allowed
Processing positive number: 20
この例では、独自の NegativeNumberError を定義し、特定の条件下でそれを発生させました。その後、try...except ブロックがこのカスタムエラー型を具体的に捕捉し、エラー処理をより正確にしています。
まとめ
この実験では、Python で堅牢なエラーハンドリングを実装する方法を学びました。まず、try...except ブロックを使用して、ユーザー入力からの特定の ValueError を捕捉しました。次に、複数の例外タイプを個別に、または単一のブロックで処理することで、これを拡張しました。また、例外が発生しなかった場合にのみコードを実行するための else 句と、すべての場合でクリーンアップコードを実行するための finally 句の使用方法についても学習しました。最後に、アプリケーション固有のエラーを処理するためにカスタム例外を作成および発生させる練習を行い、コードの可読性と保守性を向上させました。



