Python の例外は、プログラムの実行時に発生する重要なイベント、通常はエラーを通知するために使用される構造体です。
例外が適切に “捕捉” (つまり正しく処理) されないと、プログラムが停止してしまうかもしれません。
もし、あなたのプログラムが実行されたときに例外を発生させるかもしれないと思ったら、次のセクションで紹介する try/except
を使って例外を処理すると便利でしょう。
>
このガイドでは、Python の例外とは何か、最も一般的な例外の種類、そして発生した例外を try
節と except
節を使ってどのように処理するかについて紹介します。
例外の処理
以下の例では、ユーザーに数値の入力を促し、実行後、与えられた数値の2乗の値を出すプログラムです。
このプログラムは、入力として数字を入力する限り、動作します。
while True:
x = int(raw_input("Please enter a number: "))
print("%s squared is %s" % (x, x**2))
文字列や “one “のような数字でない文字を入力すると、プログラムは “Value Error “という例外を発生させます。
$ python squared.py
Please enter a number: 3
3 squared is 9
Please enter a number: 4
4 squared is 16
Please enter a number: five
Traceback (most recent call last):
File "squared.py", line 4, in <module>
x = int(raw_input("Please enter a number: "))
ValueError: invalid literal for int() with base 10: 'five'
ここで例外処理の出番です。
例外を適切に処理する方法を知っておく必要があります。
特に実稼働環境では、例外を処理しないとプログラムが何をすべきかわからなくなり、クラッシュしてしまうからです。
上記のエラーをどのように処理するか見てみましょう。
これは、例外が発生しそうなプログラムを try
キーワードで囲み、それに続く except
キーワードをマッチさせて、例外が発生した場合に実行することで実現できます。
同じプログラムを書き直してみましょう。
今度は、例外が発生する可能性がある場合に対処するようにします。
while True:
try:
x = int(raw_input("Please enter a number: "))
print("%s squared is %s" % (x, x**2))
except ValueError:
print("Please enter a valid number!")
上のプログラムからわかるように、try
文の中のコードが最初に実行されます。
エラーが発生しなければ、残りのコードが実行され、 except
ステートメントはスキップされます。
例外が発生した場合(数字の代わりに文字列を入力した場合など)、プログラムは try
文にマッチした except
文を実行し、次に try/except
ブロックの外側の残りのコード(ある場合)を実行します。
try/except` 文を含むコードを実行すると何が起こるか見てみましょう。
$ python safe_squared.py
Please enter a number: 3
3 squared is 9
Please enter a number: 4
4 squared is 16
Please enter a number: five
Please enter a valid number!
Please enter a number: 5
5 squared is 25
注意: 複数の try/except
節ハンドラがあったとしても、 except
節は対応する try
節からの例外のみを処理することに注意してください。
Pythonの例外の種類
Pythonにはいくつかの組み込み例外があります。
最も一般的な例外のいくつかを見て、それらが何であり、どのように使用するかの見通しを得ることができるようにしましょう。
KeyError Exception
T
IndentationError Exception
この種の例外は、コードが適切にインデントされていない場合に発生します。
Python は中括弧を使ってスコープを指定する代わりに、インデントを使います。
したがって、インデントを正しく行うことが重要であり、それがこの例外の目的です。
ある数字が偶数かどうかをチェックする関数を書いてみましょう。
def authenticate_user(request):
try:
email = request.data['username']
password = request.data['password']
user = authenticate(email=email, password=password)
if user and user.is_active:
return Response(user_details,status=HTTP_200_OK)
else:
res = {'error': 'can not authenticate with the given credentials'}
return Response(res, status=status.HTTP_400_BAD_REQUEST)
except KeyError:
res = {'error': 'please provide a username and a password'}
この関数は、2 行目と 4 行目の両方でインデントエラーとなります。
なぜなら、この関数はコードが 4 ではなく 8 のスペースでインデントされることを想定しているからです。
このプログラムを実行すると、次のような出力が得られます。
def is_even(number):
if number % 2 == 0:
print(" %s is an even number" % (number))
else:
print("%s is an odd number" % (number))
print(is_even(1))
print(is_even(2))
SyntaxError Exception
これはPythonで最も一般的な例外の種類の1つです。
コードの構文に間違いがある場合に発生します。
以下の例を見てみましょう。
$ python is_even.py
File "is_even.py", line 3
print(" %s is an even number" % (number))
^
IndentationError: expected an indented block
このコードの出力は、”it’s odd” という文字列が引用符で囲まれていないため、3行目で構文が無効となります。
def is_odd(n):
if n % 2 != 0:
print(it's odd)
else:
print("not odd")
print(is_odd(7))
構文エラーにはさまざまな種類があり、これはほんの一例に過ぎないことを覚えておいてください。
TypeError Exception
この例外は、指定されたデータ型に対して無効な操作や関数を実行しようとしたときに発生します。
以下の例では、関数 sum_of_numbers
は 2 つの引数を受け取り、それらを足し算します。
この関数を 3 つの引数で呼び出そうとすると、2 つの引数のみを想定しているため、TypeError 例外が発生します。
$ python is_odd.py
File "is_odd.py", line 3
print(it's odd)
^
SyntaxError: EOL while scanning string literal
このコードを実行すると、次のような結果になります。
def sum_of_numbers(a, b):
return a + b
print(sum_of_numbers(1, 2, 7))
Try/except、else、finally句について
例外処理には他にもいくつかの要素があり、それが else
節と finally
節です。
私たちはすでに try 文と catch 文を使うことができ、これらはエラーをキャッチするために使われます。
ここでは、else
文とfinally
文についても見てみましょう。
その他
else節は、プログラムが例外を発生させなかったときにコードを実行するために使用されます。
また、try節にコードを追加するよりも、
else節を使用したほうがよいでしょう。
これは、try/except
文で保護されているコードで発生しなかった例外を、意図せずキャッチしてしまうことを避けるためです。
このチュートリアルの最初に使った例を考えてみましょう。
しかし、その代わりに else
文の中で print
文を実行することにします。
$ python sum_of_numbers.py
Traceback (most recent call last):
File "sum_of_numbers.py", line 4, in <module>
print(sum_of_numbers(1, 2, 7))
TypeError: sum_of_numbers() takes exactly 2 arguments (3 given)
このコードを実行すると、エラーが起こりやすい int(raw_input(...))
コードが try
文に、「安全な」コードが else
文に分離されることを除いて、前と同じ機能が提供されます。
while True:
try:
x = int(raw_input("Please enter a number: "))
except ValueError:
print("Please enter a valid number!")
else:
print("%s squared is %s" % (x, x**2))
♪やっとこさ ♪やっとこさ
この節は、例外が発生したかどうかに関係なく実行されなければならないクリーンアップのアクションを定義するためのものです。
finally節は、例外が発生したかどうかに関わらず、常に
try/except` 文を抜ける前に実行されなければなりません。
これは通常、開いているファイルを閉じるなど、後始末をするために使用されます。
この例では、finally
節を含めてみましょう。
$ python else_squared.py
Please enter a number: 3
3 squared is 9
Please enter a number: 4
4 squared is 16
Please enter a number: five
Please enter a valid number!
Please enter a number: 5
5 squared is 25
このコードを実行すると、例外が発生したかどうかに関係なく、ループが何回実行されたかを見ることができることを除けば、前と同じように実行できます。
count = 0
while True:
try:
x = int(raw_input("Please enter a number: "))
except ValueError:
print("Please enter a valid number!")
else:
print("%s squared is %s" % (x, x**2))
finally:
print("Ran %s time(s)" % count)
結論
このガイドでは、 try/except
文を使用して Python で例外を処理する方法を、オプションの構成要素である else
と finally
を含めて簡単に説明しました。
このチュートリアルで、Pythonの例外処理に関する混乱が解消されれば幸いです。
もっと学びたいのであれば、Pythonドキュメントの Errors and Exceptions のセクションでより多くの情報を得ることができます。
</module