Pythonでの例外処理


導入


ソフトウェアを作成するのは難しい仕事です.あなたのソフトウェアをより良くするために、あなたのアプリケーションは、予期しないことが起こるときでも、働き続けなければなりません.たとえば、アプリケーションが何らかのAPIからデータをプルする必要があるとしましょう.APIサーバがダウンしていて、それが必要に応じて応答しない場合はどうなります.さて、あなたは何APIがわからない場合は、心配しないでください.チェックアウトthis guide APIの詳細については.
他の一般的な問題は、ユーザーが無効な入力を入力するか、存在しないファイルを開くしようとするユーザーを含めることができます.
これらのケースの全てはPythonの組み込みの例外処理機能を使用して処理することができます.これは通常、tryとexcept文と呼ばれます.
このブログでは、次のことを学びます.
  • 共通例外
  • 例外の処理
  • 例外の増加
  • ユーザ定義例外
  • 使用finally 声明
  • 使用else 声明
  • 共通例外
    Pythonはさまざまな例外をサポートしています.最初に言語を使い始めるとき、あなたが見そうなもののリストがあります.

  • 例外-すべての他の例外が広がる基本クラス.

  • AttributeError -属性参照または割り当てが失敗したときに送出されます.

  • InsertError -インポート文がモジュール定義を見つからない場合に発生します.

  • ModulenotFounderError -モジュールが配置できない場合にimportによって発生されるImportErrorのサブクラス

  • IndexError -シーケンスのサブスクリプトが範囲外であるときに送出されます.

  • keyError -キーが辞書で見つからないときに送出されます.

  • keyboardInterrupt -ユーザが割り込みキー(通常はControl - CまたはDelete )を押すと送出されます.

  • nameError -ローカルまたはグローバル名が見つからない場合に発生します.

  • oserror -関数がシステム関連のエラーを返すと送出される

  • runtimeerror -エラーが検出されたときに送出されます.エラーが検出された場合、他のカテゴリには該当しません

  • syntaxErrorパーサが構文エラーに遭遇したときに送出されます

  • TypeError -操作や関数が不適切な型のオブジェクトに適用されたときに送出されます.

  • valueError -組み込み操作または関数が適切な値を持つ引数を受け取るときに送出されますが、不適切な値

  • ZeroDivisionエラー-除算またはモジュロ演算の2番目の引数がゼロのときに送出されます.
  • 組み込みの例外の完全なリストについては、Pythonドキュメントをチェックアウトすることができますhere .

    例外の処理


    Pythonには例外をキャッチするための特別な構文があります.try/except文と呼ばれます.構文は以下のようになります:
    try:
        # Do something that may raise exception
    except ExceptionName:
        # Handle the exception
    
    try ブロックは、通常、例外を発生させる可能性のあるコードを置きます.にexcept ブロック、tryブロックで発生した例外を処理します.このコードはexcept 例外の名前がExceptionNameに一致する場合のみブロックが実行されます.たとえば、システムに存在しないファイルをオープンしようとすると、filenotFoundErrorを取得します.
    with open("test.txt") as f:
        data = f.readlines()
    
    print(data)
    
    出力:
    $ py test.py 
    Traceback (most recent call last):
      File "C:\Users\ashut\Desktop\Test\hello\test.py", line 1, in <module>
        with open("test.txt") as f:
    FileNotFoundError: [Errno 2] No such file or directory: 'test.txt'
    
    この例外を扱うには、次のように書きます.
    try:
        with open("test.txt") as f:
            data = f.readlines()
        print(data)
    except FileNotFoundError:
        print("File could not be found!!")
    
    
    出力:
    $ py test.py 
    File could not be found!!
    
    また、私たちはexcept 例外名を指定しないでください.これは裸の例外と呼ばれますが、推奨されません.それが悪い練習を除いて裸を作成するために悪い理由は、あなたがキャッチしている例外の種類、または正確にどこに起こっているのかわからないことです.これはあなたが間違ってより困難なことを考え出すことができます.あなたがどのように対処するために知っているものには、例外タイプを絞り込む場合は、予期しないものは有用なメッセージを使用してアプリケーションのクラッシュを行います.その時点で、他の例外をキャッチするかどうかを判断できます.
    try:
        with open("test.txt") as f:
            data = f.readlines()
        print(data)
    except:
        print("Something went wrong!")
    
    
    このコードはまだ動作して出力されます.
    $ py test.py 
    Something went wrong!
    
    しかし、この場合、我々は正確に何が間違っていたか理解できませんでした.

    複数の例外処理


    複数の例外を扱うことさえできます.仮に、存在しないファイルをオープンし、インストールされていない外部ライブラリをインポートしようとします.これは2つの例外を送出します- filenotFoundErrorとInsertError.以下のように扱うことができます.
    try:
        with open("test.txt") as f:
            data = f.readlines()
        print(data)
        from fastapi import FastAPI
    except FileNotFoundError:
        print("File could not be found!!")
    except ImportError:
        print("Library not installed!!")
    
    を返します.txtが見つからず、except FileNotFoundError ブロックとエラーメッセージを取得するファイルを見つけることができませんでした!、fastapi がインストールされていない場合、except ImportError ブロックは次の例外を扱い、この例外ハンドラーは2種類の例外のみをキャッチします.別の種類の例外が発生した場合、このハンドラはそれをキャッチしません.
    上記のコードは次のように書き換えることもできます.
    try:
        with open("test.txt") as f:
            data = f.readlines()
        print(data)
        from fastapi import FastAPI
    except (FileNotFoundError, ImportError):
        print("Something went wrong!!")
    
    しかし、上記のコードは、それが起こった正確な問題をデバッグするのをより難しくします.

    例外の増加


    例外の送出は例外の発生を強制するプロセスです.特別な場合に例外を送出します.仮に、プログラムの実行をカスタムメッセージで停止させたい場合.
    Pythonには組み込みがありますraise 例外をスローするステートメント.
    >>> raise FileNotFoundError
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    FileNotFoundError
    
    例外を発生させながらカスタムメッセージを追加できます.
    >>> raise FileNotFoundError('I am a custom message')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    FileNotFoundError: I am a custom message
    

    ユーザ定義例外


    Pythonの組み込み例外を除いて、ユーザーは独自のカスタム例外を定義できます.カスタム例外を定義するには、例外クラスを継承して新しいクラスを作成します.
    >>> class UserError(Exception):
    ... pass
    ... 
    >>> raise UserError
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    __main__.UserError
    >>> raise UserError("I am a custom error")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    __main__.UserError: I am a custom error
    
    ここでは、カスタム例外と呼ばれるUserErrorException クラス.この例外は他の例外と同様に、raise オプションのエラーメッセージを持つ文.
    カスタム例外の詳細については、例を見てみましょう.あなたが初心者だったとき、この推測の数のゲームに遭遇している可能性があります.このゲームでは、ユーザーがランダムに番号を推測するユーザーが右に取得するまでプログラムによって選択を維持します.プロセスの間、プログラムがナンバーが高いかどうかに関係なく、ユーザーを知らせ続けます.
    class ValueTooSmallError(Exception):
        """Raised when the guessed value is too small"""
        pass
    
    class ValueTooLargeError(Exception):
        """Raised when the guessed value is too large"""
        pass
    
    # guess this number
    number = 10
    
    # user guesses a number until he/she gets it right
    while True:
        try:
            user_guess = int(input("Enter a number: "))
            if user_guess < number:
                raise ValueTooSmallError
            elif user_guess > number:
                raise ValueTooLargeError
            break
        except ValueTooSmallError:
            print("Too low, try again!")
        except ValueTooLargeError:
            print("Too large, try again!")
    
    print("Congratulations! You guessed it right.")
    
    
    プログラムのサンプルランです.
    $ py test.py 
    Enter a number: 17
    Too large, try again!
    Enter a number: 3
    Too low, try again!
    Enter a number: 10
    Congratulations! You guessed it right.
    
    つのカスタム例外を作成しましたValueTooSmallError and ValueTooLargeError これは組み込みの例外クラスを継承します.
    カスタム例外の最初の例では、例外クラスの本体に何も追加しませんでした.しかし、我々は我々のニーズごとにもそれをカスタマイズすることができます.あなたが進む前に、Pythonでオブジェクト指向プログラミングを知っていることを確認してください.例を見ましょう.
    class AgeNotValidError(Exception):
        """Exception raised for errors in the age.
    
        Attributes:
            age -- input age that caused the error
            message -- explanation of the error
        """
    
        def __init__ (self, age, message="Your age must be equal to or greater than 18 years"):
            self.age = age
            self.message = message
            super(). __init__ (self.message)
    
    age = int(input("Enter your age: "))
    if not age >= 18:
        raise AgeNotValidError(age)
    
    
    出力:
    $ py test.py 
    Enter your age: 16
    Traceback (most recent call last):
      File "C:\Users\ashut\Desktop\Test\hello\test.py", line 17, in <module>
        raise AgeNotValidError(age)
    __main__.AgeNotValidError: Your age must be equal to or greater than 18 years
    
    ここでは、Exception 独自のカスタム引数を受け入れるクラスage and message . 次に、親のコンストラクタException クラスを手動でself.message 引数使用super() .
    習慣self.age 属性は後で使用するように定義されます.
    カスタムエラーメッセージも渡すことができます.
    class AgeNotValidError(Exception):
        """Exception raised for errors in the age.
    
        Attributes:
            age -- input age that caused the error
            message -- explanation of the error
        """
    
        def __init__ (self, age, message="Your age must be equal to or greater than 18 years"):
            self.age = age
            self.message = message
            super(). __init__ (self.message)
    
    age = int(input("Enter your age: "))
    if not age >= 18:
        raise AgeNotValidError(age, message=f"Your age is {age} but should be greater than or equal to 18.")
    
    
    出力:
    $ py test.py 
    Enter your age: 13
    Traceback (most recent call last):
      File "C:\Users\ashut\Desktop\Test\hello\test.py", line 17, in <module>
        raise AgeNotValidError(age, message=f"Your age is {age} but should be greater than or equal to 18.")
    __main__.AgeNotValidError: Your age is 13 but should be greater than or equal to 18.
    
    相続人__str__ メソッドException クラスを使用して、AgeNotValidError が送出されます.
    また、カスタマイズすることができます__str__ メソッド自体をオーバーライドします.
    class AgeNotValidError(Exception):
        """Exception raised for errors in the age.
    
        Attributes:
            age -- input age that caused the error
            message -- explanation of the error
        """
    
        def __init__ (self, age, message="Your age must be equal to or greater than 18 years"):
            self.age = age
            self.message = message
            super(). __init__ (self.message)
    
        def __str__ (self):
            return f"{self.message}\nGiven Age: {self.age}"
    
    age = int(input("Enter your age: "))
    if not age >= 18:
        raise AgeNotValidError(age)
    
    
    出力:
    $ py test.py 
    Enter your age: 14
    Traceback (most recent call last):
      File "C:\Users\ashut\Desktop\Test\hello\test.py", line 20, in <module>
        raise AgeNotValidError(age)
    __main__.AgeNotValidError: Your age must be equal to or greater than 18 years
    Given Age: 14
    

    finally文の使用


    試してみてブロックを除くと、オプションで最終的にブロックを追加することもできます.tryブロックで例外が発生しても、finallyブロックは常に実行されます.たとえば、最後のブロックでファイルを閉じるコードを追加できます.
    try:
        f = open("hello.txt", "w")
        import fastapi
    except ImportError:
        print("An ImportError occurred")
    finally:
        f.close()
        print("Closed the file")
    
    出力:
    $ py test.py 
    An ImportError occurred
    Closed the file
    
    上記のコードのtryブロックで、それを書くファイルを開きました.その後、システムにインストールされていないライブラリをインポートしました.これはimportブロックを引き起こします.finallyブロックでファイルを閉じました.
    例外を処理しない場合でも、finallyブロックはまだ実行されます.
    try:
        f = open("hello.txt", "w")
        import fastapi
    finally:
        f.close()
        print("Closed the file")
    
    出力:
    $ py test.py 
    Closed the file
    Traceback (most recent call last):
      File "C:\Users\ashut\Desktop\Test\hello\test.py", line 3, in <module>
        import fastapi
    ModuleNotFoundError: No module named 'fastapi'
    
    閉じるこの動画はお気に入りから削除されています.

    else文の使用


    例外がない場合、else文は実行されます.
    try:
        print("I am try block")
    except ImportError:
        print("I am except block")
    else:
        print("I am else block")
    
    出力:
    $ py test.py 
    I am try block
    I am else block
    
    例外が発生しなかったので、tryとelseブロックが実行されました.
    例外を上げ、次に何が起こるかを見ましょう.
    try:
        raise ImportError
        print("I am try block")
    except ImportError:
        print("I am except block")
    else:
        print("I am else block")
    
    出力:
    $ py test.py 
    I am except block
    
    現在、tryとexceptブロックだけが実行されたことがわかります.また、tryブロック内のprint文は、例外が発生するたびに、その行の下のステートメントがスキップされるため、実行されませんでした.

    ラッピング


    このブログではPythonでの例外処理方法を学びました.学習例外処理は、予期しない場合でも、コードが非常により良い方法で動作するように重要です.
    あなたはブログを読んでいただきありがとうございます!