Python例外:はじめに

Python例外:はじめに

Pythonプログラムは、エラーが発生するとすぐに終了します。 Pythonでは、エラーは構文エラーまたは例外です。 この記事では、例外とは何か、そして例外が構文エラーとどのように異なるかについて説明します。 その後、例外の発生とアサーションの作成について学習します。 次に、try and exceptブロックのデモンストレーションで終了します。

An introduction to exceptions in Python

無料のPDFダウンロード: Python3チートシート

例外と構文エラー

構文エラーは、パーサーが誤ったステートメントを検出したときに発生します。 次の例をご覧ください。

>>> print( 0 / 0 ))
  File "", line 1
    print( 0 / 0 ))
                  ^
SyntaxError: invalid syntax

矢印は、パーサーがsyntax errorに遭遇した場所を示しています。 この例では、1つのブラケットが多すぎます。 それを削除して、コードを再度実行します。

>>> print( 0 / 0)
Traceback (most recent call last):
  File "", line 1, in 
ZeroDivisionError: integer division or modulo by zero

今回は、exception errorに遭遇しました。 このタイプのエラーは、構文的に正しいPythonコードがエラーになるたびに発生します。 メッセージの最後の行は、どのタイプの例外エラーに遭遇したかを示しています。

Pythonは、メッセージexception errorを表示する代わりに、発生した例外エラーのタイプを詳しく説明します。 この場合、それはZeroDivisionErrorでした。 Pythonには、various built-in exceptionsと、自己定義の例外を作成する機能が付属しています。

例外を発生させる

条件が発生した場合、raiseを使用して例外をスローできます。 このステートメントは、カスタム例外で補完できます。

Illustration of raise statement usage

raiseを使用して特定の条件が発生したときにエラーをスローしたい場合は、次のように対処できます。

x = 10
if x > 5:
    raise Exception('x should not exceed 5. The value of x was: {}'.format(x))

このコードを実行すると、出力は次のようになります。

Traceback (most recent call last):
  File "", line 4, in 
Exception: x should not exceed 5. The value of x was: 10

プログラムは停止し、画面に例外を表示して、何が間違っていたかについての手がかりを提供します。

AssertionError例外

プログラムが途中でクラッシュするのを待つ代わりに、making an assertion in Pythonで開始することもできます。 特定の条件が満たされていることをassertします。 この条件がTrueであることが判明した場合、それは優れています! プログラムは続行できます。 条件がFalseであることが判明した場合、プログラムにAssertionError例外をスローさせることができます。

Python assert statement

Linuxシステムでコードが実行されると断言されている次の例をご覧ください。

import sys
assert ('linux' in sys.platform), "This code runs on Linux only."

このコードをLinuxマシンで実行すると、アサーションは成功します。 このコードをWindowsマシンで実行すると、アサーションの結果はFalseになり、結果は次のようになります。

Traceback (most recent call last):
  File "", line 2, in 
AssertionError: This code runs on Linux only.

この例では、AssertionError例外をスローすることが、プログラムが最後に行うことです。 プログラムは停止し、継続しません。 それがあなたの望むものではない場合はどうなりますか?

tryおよびexceptブロック:例外の処理

Pythonのtryおよびexceptブロックは、例外をキャッチして処理するために使用されます。 Pythonは、tryステートメントに続くコードをプログラムの「通常の」部分として実行します。 exceptステートメントに続くコードは、前のtry句の例外に対するプログラムの応答です。

Diagram showing try and except statements

前に見たように、構文的に正しいコードでエラーが発生すると、Pythonは例外エラーをスローします。 この例外エラーは、処理されない場合にプログラムをクラッシュさせます。 except句は、プログラムが例外にどのように応答するかを決定します。

次の関数は、tryおよびexceptブロックを理解するのに役立ちます。

def linux_interaction():
    assert ('linux' in sys.platform), "Function can only run on Linux systems."
    print('Doing something.')

linux_interaction()は、Linuxシステムでのみ実行できます。 この関数のassertは、Linux以外のオペレーティングシステムで呼び出すと、AssertionError例外をスローします。

次のコードを使用して、関数にtryを与えることができます。

try:
    linux_interaction()
except:
    pass

ここでエラーを処理する方法は、passを配ることです。 このコードをWindowsマシンで実行すると、次の出力が得られます。

何もありません。 ここでの良い点は、プログラムがクラッシュしなかったことです。 ただし、コードを実行するたびに何らかのタイプの例外が発生したかどうかを確認できたらうれしいです。 このために、passを次のように有益なメッセージを生成するものに変更できます。

try:
    linux_interaction()
except:
    print('Linux function was not executed')

Windowsマシンでこのコードを実行します。

Linux function was not executed

この関数を実行しているプログラムで例外が発生すると、プログラムは続行し、関数呼び出しが成功しなかったという事実を通知します。

表示されなかったのは、関数呼び出しの結果としてスローされたエラーのタイプです。 何が間違っていたのかを正確に確認するには、関数がスローしたエラーをキャッチする必要があります。

次のコードは、AssertionErrorをキャプチャし、そのメッセージを画面に出力する例です。

try:
    linux_interaction()
except AssertionError as error:
    print(error)
    print('The linux_interaction() function was not executed')

Windowsマシンでこの関数を実行すると、次が出力されます。

Function can only run on Linux systems.
The linux_interaction() function was not executed

最初のメッセージはAssertionErrorで、関数はLinuxマシンでのみ実行できることを通知します。 2番目のメッセージは、実行されなかった機能を示します。

前の例では、自分で作成した関数を呼び出しました。 関数を実行すると、AssertionError例外がキャッチされ、画面に出力されました。

ファイルを開いて組み込み例外を使用する別の例を次に示します。

try:
    with open('file.log') as file:
        read_data = file.read()
except:
    print('Could not open file.log')

file.logが存在しない場合、このコードブロックは次を出力します。

Could not open file.log

これは情報メッセージであり、プログラムは引き続き実行されます。 Python docsには、ここで使用できる組み込みの例外がたくさんあることがわかります。 そのページで説明されている1つの例外は次のとおりです。

例外FileNotFoundError

ファイルまたはディレクトリが要求されたが、存在しない場合に発生します。 errno ENOENTに対応します。

このタイプの例外をキャッチして画面に出力するには、次のコードを使用できます。

try:
    with open('file.log') as file:
        read_data = file.read()
except FileNotFoundError as fnf_error:
    print(fnf_error)

この場合、file.logが存在しない場合、出力は次のようになります。

[Errno 2] No such file or directory: 'file.log'

try句に複数の関数呼び出しを含めることができ、さまざまな例外のキャッチを予期できます。 ここで注意すべきことは、try句のコードは、例外が発生するとすぐに停止するということです。

Warning:Exceptionをキャッチすると、すべてのエラーが非表示になります。完全に予期しないエラーも含まれます。 これが、Pythonプログラムで裸のexcept句を避ける必要がある理由です。 代わりに、キャッチして処理するspecific exception classesを参照することをお勧めします。 これが良いアイデアin this tutorialである理由について詳しく知ることができます。

次のコードを見てください。 ここでは、最初にlinux_interaction()関数を呼び出してから、ファイルを開こうとします。

try:
    linux_interaction()
    with open('file.log') as file:
        read_data = file.read()
except FileNotFoundError as fnf_error:
    print(fnf_error)
except AssertionError as error:
    print(error)
    print('Linux linux_interaction() function was not executed')

ファイルが存在しない場合、Windowsマシンでこのコードを実行すると、次が出力されます。

Function can only run on Linux systems.
Linux linux_interaction() function was not executed

try句内で、すぐに例外が発生し、file.logを開こうとした部分に到達しませんでした。 Linuxマシンでコードを実行するとどうなるかを見てみましょう。

[Errno 2] No such file or directory: 'file.log'

主なポイントは次のとおりです。

  • try句は、最初の例外が発生するポイントまで実行されます。

  • except句、または例外ハンドラー内で、プログラムが例外にどのように応答するかを決定します。

  • 複数の例外を予測し、プログラムがそれらにどのように応答するかを区別できます。

  • 裸のexcept句の使用は避けてください。

else

Pythonでは、elseステートメントを使用して、例外がない場合にのみ特定のコードブロックを実行するようにプログラムに指示できます。

Diagram of try

次の例を見てください。

try:
    linux_interaction()
except AssertionError as error:
    print(error)
else:
    print('Executing the else clause.')

このコードをLinuxシステムで実行すると、出力は次のようになります。

Doing something.
Executing the else clause.

プログラムで例外が発生しなかったため、else句が実行されました。

tryを使用して、else句内でコードを実行し、そこで発生する可能性のある例外をキャッチすることもできます。

try:
    linux_interaction()
except AssertionError as error:
    print(error)
else:
    try:
        with open('file.log') as file:
            read_data = file.read()
    except FileNotFoundError as fnf_error:
        print(fnf_error)

Linuxマシンでこのコードを実行すると、次の結果が得られます。

Doing something.
[Errno 2] No such file or directory: 'file.log'

出力から、linux_interaction()関数が実行されたことがわかります。 例外が発生しなかったため、file.logを開こうとしました。 そのファイルは存在せず、ファイルを開く代わりに、FileNotFoundError例外をキャッチしました。

finally使用後のクリーンアップ

コードを実行した後にクリーンアップするために、何らかのアクションを常に実装しなければならないと想像してください。 Pythonでは、finally句を使用してこれを行うことができます。

Diagram explaining try except else finally statements

次の例を見てください。

try:
    linux_interaction()
except AssertionError as error:
    print(error)
else:
    try:
        with open('file.log') as file:
            read_data = file.read()
    except FileNotFoundError as fnf_error:
        print(fnf_error)
finally:
    print('Cleaning up, irrespective of any exceptions.')

前のコードでは、finally句のすべてが実行されます。 try句またはelse句のどこかで例外が発生したかどうかは関係ありません。 Windowsマシンで前のコードを実行すると、次の結果が出力されます。

Function can only run on Linux systems.
Cleaning up, irrespective of any exceptions.

まとめ

構文エラーと例外の違いを見た後、Pythonで例外を発生、キャッチ、および処理するさまざまな方法について学びました。 この記事では、次のオプションを見ました。

  • raiseを使用すると、いつでも例外をスローできます。

  • assertを使用すると、特定の条件が満たされているかどうかを確認し、満たされていない場合は例外をスローできます。

  • try句では、例外が発生するまですべてのステートメントが実行されます。

  • exceptは、try句で発生した例外をキャッチして処理するために使用されます。

  • elseを使用すると、try句で例外が発生していない場合にのみ実行する必要があるセクションをコーディングできます。

  • finallyを使用すると、以前に発生した例外の有無にかかわらず、常に実行する必要のあるコードのセクションを実行できます。

無料のPDFダウンロード: Python3チートシート

この記事が、例外を処理するときにPythonが提供しなければならない基本的なツールの理解に役立つことを願っています。