Python PR

【Python】try文を使った例外処理の方法

記事内に商品プロモーションを含む場合があります

この記事では、Pythonで例外処理する方法を解説します。

例外処理とは、エラーや例外が発生した時に実行される処理のことを言います。「エラー処理」とも呼ばれたりします。

プログラムを実行しているとエラーや例外が発生する可能性があります。エラーが発生する原因はさまざまですが、適切に例外処理しないとプログラムはクラッシュしたり、予期しない結果を生成したりする可能性があります。

Pythonでは、これらのエラーを適切に処理するためにtry/exceptブロックを使用します。

それでは、例外処理の方法を見ていきましょう!

例外処理の基本

例外処理をするにはtry/exceptを使います。

try:
    # エラーが発生しそうな処理
except:
    # tryブロック内でエラーが発生した場合の処理

try文ブロック内でエラーが発生した場合、except節が処理されます。try文内でエラーが発生しなかった場合、except節は無視されます。

以下のコードは、input()関数で受け取った値をint型に変換します。受け取った値がint型に変換できない際にエラーが発生するので例外処理を行っています。

value = input('整数を入力: ')

try:
    # int型に変換できないとValueError発生
    value = int(value)
except:
    # try文でエラーが発生すると実行される
    print('valueはintに変換できません')

実行結果

整数を入力: one
valueはintに変換できません

input()関数で受け取ったvalueの値がint型に変換できない場合にtry文ブロック内でValueErrorが発生し、exceptに定義されている処理が実行されます。

このように、try文ブロックにエラーを発生させそうな処理を記述し、exceptにエラーが発生した際の処理を定義して例外処理を行います。

発生したエラーで処理を分岐させる

try文ブロック内で発生したエラーの型によって処理を分岐させることができます。エラーによって処理を分岐するには分岐させたいエラーの型を指定したexcept節を定義します。

try:
    # エラーが発生しそうな処理
except 例外:
    # 指定した例外が発生した場合にこのブロックが実行される

以下のコードでは、ValueError例外、またはZeroDivisionError例外が発生した際に実行されるexcept節を定義しました。

value = input('整数を入力: ')

try:
    # intに変換できないとValueError発生
    value = int(value)

    # valueが0だとZeroDivisionError発生
    div = 10 / value

except ValueError:
    # tryブロックでValueErrorが発生すると実行される
    print('valueはintに変換できません')

except ZeroDivisionError:
    # tryブロックでZeroDivisionErrorが発生すると実行される
    print('0で割ることはできません')

実行結果

整数を入力: 0
0で割ることはできません

しかし、発生したエラーに対応するexcept節が存在しなければエラーがそのまま発生してしまうので注意してください。以下のコードではtry文ブロック内でZeroDivisionErrorが発生しますが、except: ValueErrorしか定義されていないためエラーが発生してしまう。

try:
    # ZeroDivisionError発生
    div = 10 / 0

except ValueError:
    print('intに変換できません')

実行結果

Traceback (most recent call last):
  File "/Users/user/Desktop/Python/main.py", line 3, in 
    div = 10 / 0
          ~~~^~~
ZeroDivisionError: division by zero

エラーの種類を知りたい方は以下のページを参考にしてください。

外部リンク具象例外 - 組み込み例外 — Python ドキュメント

エラーが発生しなかったときの処理: else節

try文のオプションとしてelse節を定義できます。else節は、except節の後に記述します。

try:
    # なんらかの処理
except:
    # tryブロック内でエラーが発生した場合の処理
else:
    # エラーが発生しなかったときの処理

else節はtry文ブロックでエラーが発生しなかった時に実行されます。以下のコードでは、エラーが発生しなかった場合にelse節で商を出力します。

value = input('整数を入力: ')

try:
    # intに変換できないとValueError発生
    value = int(value)

    # valueが0だとZeroDivisionError発生
    div = 10 / value

except ValueError:
    print('valueはintに変換できません')

except ZeroDivisionError:
    print('0で割ることはできません')
else:
    # エラーが発生しなかったら結果を出力
    print(f'結果: {div}')

実行結果

整数を入力: 2
結果: 5.0

クリーンアップ: finally節

try文のオプションとしてfinally節を定義できます。finally節は、一番最後に記述します。

try:
    # なんらかの処理
except:
    # tryブロック内でエラーが発生した場合の処理
else:
    # エラーが発生しなかったときの処理
finally:
    # エラーの発生に関係なく最後に実行される処理

finally節は例外処理の最後に必ず実行されます。以下のコードでは、finally節でそれ以降使用しない変数valueを削除しています。

value = input('整数を入力: ')

try:
    # intに変換できないとValueError発生
    value = int(value)

    # valueが0だとZeroDivisionError発生
    div = 10 / value

except ValueError:
    print('valueはintに変換できません')

except ZeroDivisionError:
    print('0で割ることはできません')
else:
    # エラーが発生しなかったら結果を出力
    print(f'結果: {div}')
finally:
    # 例外処理の最後に実行される
    del value

finally節は、ファイルを閉じたり、リソースを解放したり、接続を閉じたりといったクリーンアップ操作に使われます。これらの操作は、エラーが発生した際にも正常に処理が完了したときにも必要なのでfinally節に定義しておくと安全です。

例外の取得

except節で発生した例外のインスタンスを任意の変数に代入することができます。except節の後ろに例外 as 変数を記述することで変数に例外のインスタンスを代入します。

try:
    # エラーが発生しそうな処理
except 例外 as 変数:
    # 変数に代入した例外のインスタンスが使用可能

以下のコードでは、type()関数を使って発生した例外の型名を出力しています。ちなみに、システム終了以外の全ての組み込み例外はExceptionから派生しているので、Exceptionを指定することでほぼ全ての例外を受け取ることができます。

value = input('整数を入力: ')

try:
    # intに変換できないとValueError発生
    value = int(value)

    # valueが0だとZeroDivisionError発生
    div = 10 / value
except Exception as e:
    print(type(e))

実行結果

整数を入力: one
<class 'ValueError'>
整数を入力: 0
<class 'ZeroDivisionError'>

エラーメッセージの出力

取得した例外のインスタンスを出力することでエラーメッセージを出力することができます。

value = input('整数を入力: ')

try:
    # intに変換できないとValueError発生
    value = int(value)

    # valueが0だとZeroDivisionError発生
    div = 10 / value
except Exception as e:
    print(e)

実行結果

整数を入力: one
invalid literal for int() with base 10: 'one'
整数を入力: 0
division by zero

スタックトレースの表示

標準モジュールであるtracebackprint_exc()メソッドを呼び出すことで発生したエラーのスタックトレースを表示することができます。

import traceback

value = input('整数を入力: ')

try:
    # intに変換できないとValueError発生
    value = int(value)

    # valueが0だとZeroDivisionError発生
    div = 10 / value
except:
    # デバッグの際のみ実行
    if __debug__:
        # トレースバックの出力
        traceback.print_exc()

実行結果

整数を入力: 0
Traceback (most recent call last):
  File "/Users/user/Desktop/Python/main.py", line 10, in 
    div = 10 / value
          ~~~^~~~~~~
ZeroDivisionError: division by zero

上記コードでは、デバッグモードで実行した際のみトレースバックを表示します。デバッグモードについては以下の記事を参照してください。

Linkデバッグに使われるassert文の使い方

まとめ

この記事では、Pythonの例外処理について解説しました。

「ここエラーが発生するかもなぁ」と事前に想定できる場合は、try文を使ってエラーが発生した際の処理を定義しておきましょう!

それでは今回の内容はここまでです!ではまたどこかで〜( ・∀・)ノ