エラーと例外について
● エラーの種類
エラーの種類は数多くありますが、基本的には、構文エラーと例外に分類できます。
構文エラーと例外について復習していきます。
構文エラーとは
構文エラー(SyntaxError)とは、構文が間違っていることで発生するエラーです。
構文が誤っていると、SyntaxErrorとのエラーが表示されます。
print(
# print(
# ^
# SyntaxError: incomplete input
また、インデントが不適切な場合も構文エラーが発生します。
インデントが不適切な場合、IndentationErrorとのエラーが表示されます。
for i in range(5):
print("Hello") # インデントがない
# print("Hello")
# ^
# IndentationError: expected an indented block after 'for' statement on line 1
例外とは
コードを実行した際、構文以外でエラーが検知された場合もエラーが発生することがあります。
この場合に発生するエラーを例外と言います。
※代表例
- ZeroDivisionError
- NameError
- TypeError
- ValueError
3 / 0
# ZeroDivisionError: division by zero
name ** 2
# NameError: name 'name' is not defined
"abc" + 3
# TypeError: can only concatenate str (not "int") to str
int("Hello World")
# ValueError: invalid literal for int() with base 10: 'Hello World'
例外処理について
● try文
try
文を使用することで、特定の例外が発生した際の処理を指定できます。
while True:
try:
x = int(input("数字を入力してください:")) # 検証したいコード
except ValueError: # 起こりうるエラーの名前
print("入力に誤りがあります。もう一度入力してください。") # 起こりうるエラーが起きたときの処理
else:
break
● raise文
raise
文を使って強制的に例外を発生させることもできます。
raise TypeError("raise文のテスト")
# TypeError: raise文のテスト
例外が発生した際に特定の処理を実行した後で、再度例外を表示させたい場合は
例外処理の後にraise
を記述します。例外が発生した際に、ログを記録として残した後で再び例外を出力したい場合などに有効です。
try:
x = int(input("数字を入力してください:")) # 検証したいコード
except ValueError: # 起こりうるエラーの名前
print("入力に誤りがあります。もう一度入力してください。") # 起こりうるエラーが起きたときの処理
raise
# 数字を入力してください:a
# 入力に誤りがあります。もう一度入力してください。
# ValueError: invalid literal for int() with base 10: 'a'
※ raise文について、追記予定
問題
下記の実行結果を求めよ
print("出力結果:")
try:
raise Exception("開始前","Exception発生")
print("開始")
except IOError as msg:
print("IOError発生:",msg.args[0])
except Exception as msg:
print("予期せぬ問題発生:",msg.args[1])
else:
print("Else表示")
# 出力結果:予期せぬ問題発生: Exception発生
● 解説
- 最初に、"出力結果:"という文字列が表示されます。
-
try
:ブロックが開始されます。 -
raise Exception("開始前", "Exception発生")
が実行されます。この行により、Exception
という種類の例外が発生します。例外は引数として2つの文字列を持っています。 -
except IOError as msg:
に移動しますが、IOError
の例外は発生していないため、このブロックはスキップされます。 -
except Exception as msg:
に移動します。ここで発生した例外は、先ほどのraise
文で発生したException
です。Exception
の例外はキャッチされ、msg
という変数に例外の情報が代入されます。 -
print("予期せぬ問題発生:", msg.args[1])
が実行されます。この行では、例外の第2引数である"Exception発生"
が表示されます。 -
else:
ブロックに移動しますが、前のexcept
ブロックが実行されたため、このブロックはスキップされます。 - プログラムの実行が終了します。
※注意点として、raise
文で例外が発生すると、それ以降のコードは実行されず、例外処理が行われます。そのため、print("開始")
は実行されずにスキップされます。
try:
raise NameError("Hello", "World")
except NameError as inst:
print(inst.args[0])
raise
# HelloとNameError
● 解説
-
try:
ブロックが開始されます。 -
raise NameError("Hello", "World")
が実行されます。この行により、NameError
という種類の例外が発生します。例外は引数として2つの文字列を持っています。 -
except NameError as inst:
に移動します。ここで発生した例外は、先ほどのraise
文で発生したNameError
です。NameError
の例外はキャッチされ、inst
という変数に例外の情報が代入されます。 -
print(inst.args[0])
が実行されます。この行では、例外の第1引数である"Hello"
が表示されます。 -
raise
文が再度実行されます。これにより、現在の例外が再度発生します。 - プログラムの実行が終了します。
try:
raise ValueError
except ValueError:
print("Hello World")
# Hello World
● 解説
-
try:
:この行から始まるブロックは、例外が発生する可能性のあるコードを含んでいます。例外が発生すると、それに対応するexcept
ブロックが実行されます。 -
raise ValueError
:この行は、ValueError
という種類の例外を発生させます。引数を指定せずにValueErrorを発生させたため、エラーメッセージはありません。 -
except ValueError:
:この行は、ValueError
という特定の種類の例外が発生した場合に実行されるコードを定義しています。 -
print("Hello World")
:この行は、ValueError
が発生した場合に実行されるコードです。"Hello World"
というメッセージが表示されます。