Python の例外処理とカスタム例外タイプ

Python での例外と処理と使用法

異常な

プログラムの実行中に、
値が割り当てられていない変数の使用、
存在しないインデックスの使用、
0 による除算など、いくつかのエラーが必然的に発生します

これらのエラーをプログラム例外と呼びます。
プログラムの実行中に例外が発生すると、プログラムは即座に終了し、例外後のすべてのコードは実行されません。

例外を処理する

プログラムの実行中に例外が発生した場合、プログラムを直接終了することが目的ではありません。
Python は、例外が発生したときに、その例外を処理するコードを作成できることを望んでいます。

try ステートメント

try:
    代码块(可能出现错误的语句)
except 异常类型 as 异常名:
    代码块(出现错误以后的处理方式)
except 异常类型 as 异常名:
    代码块(出现错误以后的处理方式)
except 异常类型 as 异常名:
    代码块(出现错误以后的处理方式)
else:
    代码块(没出错时要执行的语句)    
finally:
    代码块(该代码块总会执行)

Try は必須です。else ステートメントが存在するかどうかは問題ではありません。
少なくとも 1 つは、excel とfinally がなければなりません。

エラーが発生する可能性のあるコードを try ステートメントに入れると、コードにエラーがなければ正常に実行され、エラーが発生した場合は、
expect 節内のコードが実行されるため、例外を処理できます。コードを使用して
例外を回避し、プログラム全体を終了させます。

例外の伝播 (例外のスロー)

関数内で例外が発生した場合、その例外が関数
内で処理された場合、例外は伝播し続けません。例外が関数内で処理されなかった場合、例外は関数呼び出しに伝播し続けます
。ハンドル 例外を受信した場合は伝播しません。処理されない場合は、
グローバル スコープ (メイン モジュール) に渡されるまで呼び出し元に伝播され続けます。それでも処理されない場合は、プログラムが終了し、例外情報が表示されます。

プログラムの実行中に例外が発生すると、すべての例外情報が特別な例外オブジェクトに保存されます。
例外が伝播すると、例外オブジェクトは実際に呼び出し側にスローされます。
例: ZeroDivisionError クラスのオブジェクトが特別に使用されます。
NameError クラスの例外オブジェクトは、変数エラー例外などを処理するために特別に使用されます

プログラムの実行中に例外処理が実行されない場合、例外はグローバル スコープ (メイン モジュール) に渡されるまで伝播し続け、グローバル スコープ (メイン モジュール) に渡された時点でプログラムは終了し、例外情報が表示されます。

以下に例を示します。

def fn():
    raise ValueError("这是一个自定义的异常")

def main():
    try:
        fn()
    except ValueError as e:
        print("发生了异常:", e)

main()

print("程序结束")

上記のコードでは、fn()関数はraiseステートメントを使用してValueError例外をスローし、例外情報は「これはカスタム例外です」として指定されています。main()関数内で、try-exceptステートメントを使用してValueError例外をキャッチし、例外情報を出力します。最後に「Program End」を出力します。

例外をスローする

raise ステートメントを使用して例外をスローできます。raise
ステートメントの後に例外クラスまたは例外のインスタンスを続ける必要があります。

コードで例外処理を使用する場合、raiseステートメントを使用してカスタム例外をスローしたり、キャッチした例外を再スローしたりできます。

以下に例を示します。

def divide(x, y):
    try:
        if y == 0:
            raise ZeroDivisionError("除数不能为零")
        result = x / y
    except ZeroDivisionError as e:
        print(e)
        raise  # 重新引发已捕获的异常
    else:
        print("结果:", result)

try:
    divide(10, 2)
    divide(10, 0)
except ZeroDivisionError as e:
    print("捕获异常:", e)

上記のコードでは、除数がゼロの場合、ステートメントを通じてraise組み込み例外を発生させ、エラー メッセージを渡します。ZeroDivisionError同時に、ブロック内のステートメントexcept ZeroDivisionErrorを使用してraiseキャッチされた例外を再スローし、外部で例外の処理を続行します。

throw Exception を使用する場合、例外クラスのインスタンスを渡すか、クラス名を使用して例外を直接発生させるかを選択できます。この場合、後者の viz を使用しましたraise ZeroDivisionError("除数不能为零")

メインのコード ブロックでは、try-exceptこれを使用してZeroDivisionError例外をキャッチし、キャッチした例外情報を出力します。divide()これにより、関数によってスローされた例外を処理できるようになります。

出力は次のとおりです。

结果: 5.0
division by zero
捕获异常: division by zero

ステートメントを使用するとraise、コード内で明示的に例外を発生させ、必要に応じて例外を処理または渡すことができます。これにより、例外処理がより柔軟かつ制御可能になり、堅牢なコードの作成に役立ちます。

Try-Except ステートメント

Python では、try-exceptステートメントを使用して、指定したタイプの例外をキャッチして処理できます。特定の種類の例外をキャッチするだけでなく、try-except複数のexceptステートメント ブロックを使用して、異なる種類の例外を個別に処理することもできます。

以下に例を示します。

def divide(x, y):
    try:
        result = x / y
        print("结果:", result)
    except ZeroDivisionError:
        print("除数不能为零")
    except TypeError:
        print("类型错误:无法进行除法运算")
    except ValueError:
        print("数值错误")
    
divide(10, 2)
divide(10, 0)
divide(10, "2")

上記のコードでは、divide()関数を使用して 2 つの数値の除算を計算し、結果を出力します。除算演算はブロック内で実行されtry、例外が発生すると、except例外の種類に基づいて対応するブロックが実行されます。

初めて呼び出されるときはdivide(10, 2)、除数がゼロではないため、例外はトリガーされず、結果が出力されます。

2 回目に呼び出されるときdivide(10, 0)、除数はゼロであり、例外がトリガされますZeroDivisionError。プログラムは対応するexcept ZeroDivisionErrorブロックを実行し、「除数をゼロにすることはできません」と出力します。

3 回目に呼び出されるときdivide(10, "2")、除数は文字列型であるため、除算は実行できません。例外が発生します。TypeErrorプログラムは対応するexcept TypeErrorブロックを実行し、「型エラー: 除算は実行できません」と出力します。

出力は次のとおりです。

结果: 5.0
除数不能为零
类型错误:无法进行除法运算

複数のブロックを使用するとexcept、さまざまな例外タイプに特定の処理コードを作成でき、プログラムで考えられるさまざまな例外をより正確に処理できるようになります。これにより、プログラムの堅牢性と信頼性が向上します。

最後にステートメント

ステートメントを使用して例外を処理するだけでなく、句をtry-except使用して、例外が発生したかどうかに関係なく実行する必要があるコード ブロックを定義することもできます。句内のコード ブロックは、例外が発生したかどうかに関係なく、ブロック内のコードが実行された後に実行されます。finallyfinallytry

以下に例を示します。

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("除数不能为零")
    finally:
        print("执行finally代码块")
    
divide(10, 2)
divide(10, 0)

上記のコードでは、divide()関数を使用して 2 つの数値の除算を計算し、例外を処理するステートメントを使用して結果を出力しますtry-except-finally

最初の呼び出しではdivide(10, 2)、除数がゼロではないため、例外はトリガーされず、結果が出力され、finallyコード ブロックが実行されます。出力は次のとおりです。

结果: 5.0
执行finally代码块

2 回目の呼び出しでは、除算器がゼロになり、例外がdivide(10, 0)トリガーされ、例外がキャッチされてエラー メッセージが出力され、コード ブロックの実行が続行されます。出力は次のとおりです。ZeroDivisionErrorfinally

除数不能为零
执行finally代码块

ご覧のとおり、コード ブロック内のコードは、例外が発生したかどうかに関係なくfinally実行されます。

finally句は通常、ファイルを閉じる、ロックを解放するなど、リソースを解放するために使用されます。これにより、例外が発生したかどうかに関係なく、プログラムの安定性とセキュリティを確保するために必要ないくつかのクリーニング操作が実行されます。

else ステートメント

ステートメントに加えて、句を使用して、ブロック内で例外が発生しない場合に実行されるコード ブロックを定義することtry-exceptもできます。elsetry

以下に例を示します。

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("除数不能为零")
    else:
        print("结果:", result)
    
divide(10, 2)
divide(10, 0)

上記のコードでは、divide()関数を使用して 2 つの数値の除算を計算し、結果を出力します。ブロック内で除算演算を実行しますtry。ゼロ除算例外が発生すると、プログラムは対応するexcept ZeroDivisionErrorブロックを実行し、「除数をゼロにすることはできません」と出力します。例外が発生しない場合、プログラムはelse句内のコード ブロックを実行し、結果を出力します。

初めて呼び出されるときはdivide(10, 2)、除数がゼロではないため、例外はトリガーされず、結果が出力されます。

2 回目に呼び出されるときdivide(10, 0)、除数はゼロであり、例外がトリガされますZeroDivisionError。プログラムは、句内のコード ブロックをexcept ZeroDivisionError実行せずに、対応するブロックを実行し、「除数をゼロにすることはできません」と出力します。else

出力は次のとおりです。

结果: 5.0
除数不能为零

句を使用するとelse、通常の処理ロジックを内部に配置できるためelse、コードがより明確かつ簡潔になります。これにより、例外処理と通常のロジック処理を明確に区別できるようになり、コードの可読性と保守性が向上します。

カスタム例外タイプ

さらに、例外タイプをカスタマイズする必要がある場合は、Exception組み込みクラスを継承して新しい例外タイプを作成し、例外をスローする必要があるときにこのタイプを使用できます。

以下に例を示します。

class MyError(Exception):
    def __init__(self, msg):
        self.msg = msg

def divide(x, y):
    try:
        if y == 0:
            raise MyError("除数不能为零")
        result = x / y
    except MyError as e:
        print(e.msg)
    else:
        print("结果:", result)
    finally:
        print("执行清理操作")

divide(10, 2)
divide(10, 0)

上記のコードでは、Exceptionクラスを継承して新しい例外タイプを作成しMyError、そのコンストラクターでエラー メッセージを渡しました。この関数ではdivide()、ゼロで除算するときにカスタム例外をスローしMyError、この例外をキャッチして処理します。else例外が発生しない場合、句内のコード ブロックが実行され、結果が出力されます。finally例外が発生するかどうかに関係なく、句内のコード ブロックが最終的に実行され、「クリーンアップ操作を実行しています」と出力されます。

出力は次のとおりです。

结果: 5.0
执行清理操作
除数不能为零
执行清理操作

例外タイプをカスタマイズすることで、独自のコードをより適切に整理および管理できるようになり、コードの読みやすさと保守性が向上します。同時に、さまざまなビジネス ニーズに合わせて、さまざまな種類の異常事態にもより柔軟に対応できます。

要約する

この記事では、Python での例外の使用と処理について紹介します。例外とは、プログラムの実行中に発生するエラーまたは例外状態であり、try-Except ステートメントを使用して捕捉して処理できます。

この記事では、まず例外とは何かを説明し、例外処理の重要性について説明します。次に、try-Except ステートメントを使用して例外をキャッチして処理する方法を紹介しました。Try ブロック内のコードは例外をスローする可能性がありますが、Exception ブロック内のコードは、対応する例外が発生した場合にのみ実行されます。

この記事では、例外が発生したかどうかに関係なく実行されるコード ブロックを定義できる Finally ステートメントについても説明しました。これは、リソースが確実に解放またはクリーンアップされるようにするのに役立ちます。

さらに、この記事では、try ブロックで例外がスローされなかった場合に実行されるコードを指定するために使用できる else ステートメントも紹介しています。このようにして、例外が発生したかどうかに応じて異なるアクションを実行できます。

最後に、この記事ではカスタム例外タイプの重要性と使用法についても触れられています。独自の例外クラスを定義することで、特定の例外状況をより適切に整理して処理できるようになり、コードがより読みやすく、保守しやすくなります。

この記事の導入部を通じて、読者は Python で例外を処理する方法と、例外メカニズムを使用してより堅牢なコードを作成する方法を学ぶことができます。同時に、例外処理の関連する概念と構文に精通していると、プログラムのエラー状態をより適切にデバッグし、処理するのに役立ちます。

おすすめ

転載: blog.csdn.net/qq_41308872/article/details/132857725