Python - 例外処理

基本的な例外処理: try, except

Python では例外が発生した場合、tryexcept を使って処理をすることができます。例えば、ゼロによる除算が行われると ZeroDivisionError 例外が発生しますが、以下の例ではその例外をエラー出力として処理しています。

try:
    print(1 / 0)
except ZeroDivisionError:
    print('Error')
# Error
基本的な例外処理: try, except

また except 例外型 as 変数名: とすることで、変数に例外オブジェクトを格納して使用することができます。

try:
    print(1 / 0)
except ZeroDivisionError as e:
    print(e)
# division by zero
基本的な例外処理: try, except

try 部分で例外が発生すると、それ以降の処理はスキップされます。以下の例のように for 文の途中で例外が発生すると、その時点で for 文は終了して except の処理に移行する。正常終了時の処理や、終了時に必ず行う処理などは後述する elsefinally で指定します。

try:
    for i in [-2, -1, 0, 1, 2]:
        print(1 / i)
except ZeroDivisionError as e:
    print(e)
# -0.5
# -1.0
# division by zero
基本的な例外処理: try, except

複数の例外処理: try, except

上記の例では ZeroDivisionError 例外は処理できますが、それ以外の例外は処理できずに途中終了します。複数の例外処理を行う場合は、except を複数指定します。except を複数指定することで、複数の例外に対してそれぞれ異なる処理を記述することができます。

def divide_each(a, b):
    try:
        print(a / b)
    except ZeroDivisionError as e:
        print('catch ZeroDivisionError:', e)
    except TypeError as e:
        print('catch TypeError:', e)

divide_each(1, 0)
# catch ZeroDivisionError: division by zero

divide_each('a', 'b')
# catch TypeError: unsupported operand type(s) for /: 'str' and 'str'
複数の例外処理: try, except

複数の例外に対して同じ処理を実行するには、except に複数の例外型をタプルで指定します。

def divide_same(a, b):
    try:
        print(a / b)
    except (ZeroDivisionError, TypeError) as e:
        print(e)

divide_same(1, 0)
# division by zero

divide_same('a', 'b')
# unsupported operand type(s) for /: 'str' and 'str'
複数の例外処理: try, except

すべての例外に対して処理を行う場合は、except から例外型を省略します。ただし、複数の except がある場合、例外型を省略できるのは最後の except のみになります。

def divide_wildcard(a, b):
    try:
        print(a / b)
    except:
        print('Error')

divide_wildcard(1, 0)
# Error

divide_wildcard('a', 'b')
# Error
複数の例外処理: try, except

システム終了以外のすべての組み込み例外の基底クラスである Exception を指定する方法もあります。

def divide_exception(a, b):
    try:
        print(a / b)
    except Exception as e:
        print(e)

divide_exception(1, 0)
# division by zero

divide_exception('a', 'b')
# unsupported operand type(s) for /: 'str' and 'str'
複数の例外処理: try, except

正常終了時の処理: else

try で例外が発生せず正常終了した後に行う処理を else に指定できます。例外が発生して except に処理が移行した場合は else の処理は実行されません。

def divide_else(a, b):
    try:
        print(a / b)
    except ZeroDivisionError as e:
        print('catch ZeroDivisionError:', e)
    else:
        print('finish (no error)')

divide_else(1, 2)
# 0.5
# finish (no error)

divide_else(1, 0)
# catch ZeroDivisionError: division by zero
正常終了時の処理: else

終了時に必ず行う処理: finally

try で例外が発生したかどうかに関わらず、必ず最後に行う処理を finally に指定できます

def divide_finally(a, b):
    try:
        print(a / b)
    except ZeroDivisionError as e:
        print('catch ZeroDivisionError:', e)
    finally:
        print('finish')

divide_finally(1, 2)
# 0.5
# finish

divide_finally(1, 0)
# catch ZeroDivisionError: division by zero
# finish
終了時に必ず行う処理: finally

elsefinally を同時に使うこともできます。正常終了時は else の処理が実行されたあとに finally の処理が実行されます。

def divide_else_finally(a, b):
    try:
        print(a / b)
    except ZeroDivisionError as e:
        print('catch ZeroDivisionError:', e)
    else:
        print('finish (no error)')
    finally:
        print('finish')

divide_else_finally(1, 2)
# 0.5
# finish (no error)
# finish

divide_else_finally(1, 0)
# catch ZeroDivisionError: division by zero
# finish
終了時に必ず行う処理: finally

例外を無視: pass

try で例外が発生しても無視する場合は pass 文を使用します。

def divide_pass(a, b):
    try:
        print(a / b)
    except ZeroDivisionError:
        pass

divide_pass(1, 0)
例外を無視: pass

関連記事