プログラムでエラーが発生すると、システムは自動的に例外を発生させます。さらに、Pythonでは、プログラムが自分で例外を発生させることもできます。例外を自分で発生させるには、raiseステートメントを使用します。
多くの場合、システムが例外を発生させるかどうかは、アプリケーションのビジネス要件に応じて決定する必要があります。プログラムのデータと実行が確立されたビジネス要件と一致しない場合、これは例外です。ビジネス要件との不一致のために生成された例外は、プログラマーによってトリガーされる必要があり、システムはそのような例外を引き起こすことはできません。
プログラムで自分で例外を発生させる必要がある場合は、raiseステートメントを使用する必要があります。 raiseステートメントには、次の3つの一般的な用途があります。
上記の3つの使用法は、最終的に例外インスタンスを発生させることであり(例外クラスが指定されている場合でも、実際にはそのクラスのデフォルトインスタンスです)、raiseステートメントは一度に1つの例外インスタンスしか発生できません。
raiseステートメントを使用して、前のGobangゲームでユーザー入力を処理したコードを書き直すことができます。
try:
# ユーザーが入力した文字列を2つの文字列に区切るには、区切り文字としてコンマ(、)を使用します
x_str, y_str = inputStr.split(sep =",")
# プレイするポイントが空でない場合
if board[int(y_str)-1][int(x_str)-1]!="+":
# デフォルトのRuntimeError例外を発生させる
raise
# 対応するリスト要素を「●」に割り当てます
board [int(y_str)-1][int(x_str)-1]= ”●”
except Exception as e:print(type(e))
inputStr =input("入力した座標は不正です。再入力してください。チェスの座標はxである必要があります。,yフォーマット\n")continue
上記のプログラムのコードの7行目は、raiseステートメントを使用して、それ自体で例外を発生させます。プログラムは、ユーザーが既存のチェスピースの座標点でチェスをプレイしようとすると、例外であると見なします。 Pythonインタープリターは、開発者によって発生した例外を受信すると、現在の実行フローも停止し、例外に対応する例外ブロックにジャンプし、例外ブロックが例外を処理します。つまり、システムによって自動的に発生する例外であろうと、プログラマーによってトリガーされる例外であろうと、Pythonインタープリターが例外を処理する方法に違いはありません。
ユーザーが例外を発生させた場合でも、それをキャッチする以外はtryを使用できます。もちろん、それを無視して、例外を上方に伝播させることもできます(呼び出し元が最初)。例外がPythonインタープリターに渡されると、プログラムは中止されます。
次の例は、ユーザー例外を処理する2つの方法を示しています。
def main():try:
# 試してみてください...例外をキャッチすることを除いて
# プログラムが異常であっても、本機能には伝わりません。
mtd(3)
except Exception as e:print('プログラムが異常です:', e)
# tryを使用しないでください...キャッチ例外を除いて、例外は広がり、プログラムを中止させます
mtd(3)
def mtd(a):if a 0:
raise ValueError("aの値が0より大きいため、要件を満たしていません")main()
上記のプログラムからわかるように、プログラムは、mtd(3)を呼び出すときに例外をキャッチするためにtryexceptを使用して、例外がexceptブロックによってキャッチされ、それを呼び出す関数に伝播されないようにするか、mtd(3)を直接呼び出すことができます。 )、関数の例外が呼び出し元の関数に直接伝播されるように、関数が例外を処理しない場合、プログラムは中止されます。
上記のプログラムを実行すると、次の出力が表示されます。
プログラムが異常です:aの値が0より大きいため、要件を満たしていません
Traceback (most recent call last):
File “C:\Users\mengma\Desktop\1.py”, line 13, in <module
main()
File “C:\Users\mengma\Desktop\1.py”, line 9, in main
mtd(3)
File “C:\Users\mengma\Desktop\1.py”, line 12, in mtd
値を上げるError( "aの値が0より大きく、要件を満たしていません")
ValueError:aの値が0より大きいため、要件を満たしていません
上記の出力の最初の行は、mtd(3)への最初の呼び出しの結果です。このメソッドによって発生した例外は、exceptブロックによってキャッチおよび処理されます。その後の大きな出力は、mtd(3)への2回目の呼び出しの結果です。例外はexceptブロックによってキャッチされなかったため、例外はPythonインタープリターに渡され、プログラムが中止されるまで上方に伝播されました。
mtd(3)の2回目の呼び出しによって発生した「File」で始まる3行の出力には、実際には異常な伝搬トラック情報が表示されます。つまり、プログラムが例外を処理しない場合、Pythonはデフォルトで例外の伝播軌跡情報をコンソールに出力します。
カスタム例外クラス
多くの場合、例外のクラス名には通常、例外に関する有用な情報も含まれているため、プログラムはカスタム例外を発生させることを選択できます。したがって、例外が発生した場合は、例外の状況を明確に説明できるように、適切な例外クラスを選択する必要があります。この場合、アプリケーションはカスタム例外を発生させる必要があることがよくあります。
ユーザー定義の例外は、Exception基本クラスまたはExceptionのサブクラスを継承する必要があります。基本的に、例外クラスをカスタマイズするときにコードを追加する必要はありません。カスタム例外クラスの親クラスを指定するだけです。
次のプログラムは、カスタム例外クラス(プログラム1)を作成します。
classAuctionException(Exception): pass
上記のプログラムは、クラス本体の定義を必要としないAuctionException例外クラスを作成するため、passステートメントをプレースホルダーとして使用できます。
ほとんどの場合、カスタム例外クラスの作成は、プログラム1と同様のコードを使用して実行できます。例外のクラス名が例外を正確に記述できるように、AuctionExceptionのクラス名を変更するだけで済みます。
ただし、レイズは一緒に使用されます
実際のアプリケーションでは、例外に対してより複雑な処理方法が必要になる場合があります。例外が発生した場合、メソッドだけでは例外を完全に処理することはできず、いくつかのメソッドが協力して例外を完全に処理する必要があります。つまり、例外が発生する現在のメソッドでは、プログラムは例外を部分的にしか処理せず、メソッドの呼び出し元で一部の処理を完了する必要があるため、メソッドの呼び出し元もキャッチできるように、例外を再度発生させる必要があります。異常な。
複数のメソッドを使用して同じ例外を共同処理するこの状況を実現するには、exceptブロックでraiseステートメントを組み合わせて実行できます。次のプログラムは、exceptとraiseの同時使用を示しています。
classAuctionException(Exception): pass
classAuctionTest:
def __init__(self, init_price):
self.init_price = init_price
def bid(self, bid_price):
d =0.0try:
d =float(bid_price)
except Exception as e:
# ここでは、単に例外情報を印刷するだけです
print("例外を変換します:", e)
# カスタム例外を再度スローする
raise AuctionException("入札価格は数値である必要があり、他の文字を含めることはできません。") # ①
raise AuctionException(e)if self.init_price d:
raise AuctionException("入札価格が開始価格よりも安いため、入札はできません!")
initPrice = d
def main():
at =AuctionTest(20.4)try:
at.bid("df")
except AuctionException as ae:
# 再度入札をキャッチ()メソッド内の例外、および例外の処理
print('main関数によってキャッチされた例外:', ae)main()
上記のプログラムの9〜13行のコードに対応する例外ブロックが例外をキャッチした後、システムは例外の文字列情報を出力し、AuctionExceptionを発生させて、AuctionExceptionを再度処理するメソッドを呼び出し元に通知します。したがって、プログラムのmain()関数、つまり、bid()メソッドの呼び出し元も、AuctionExceptionを再度キャッチして、例外の詳細な説明を出力できます。
除外とレイズのこの組み合わせは、実際のアプリケーションでは非常に一般的です。例外処理の実際のアプリケーションは、通常、次の2つの部分に分けられます。
アプリケーションのバックグラウンドでは、異常の詳細をログに記録する必要があります。
また、アプリケーションは、例外に基づいて、アプリケーションユーザーに何らかのプロンプトを伝える必要があります。
この場合、すべての例外は2つの方法で一緒に完了する必要があり、exceptおよびraiseと組み合わせる必要があります。
プログラムが元の例外の詳細情報を直接伝播する必要がある場合、上記のコード番号①が次の形式に変更されている限り、Pythonでは元の例外をカスタム例外でラップすることもできます。
raise AuctionException(e)
上げるにはパラメータは必要ありません
前に見たように、パラメータなしでraiseステートメントを使用できます。このとき、raiseステートメントはexceptブロックにあり、現在のコンテキストによってアクティブ化された例外を自動的に発生させます。それ以外の場合は、通常、デフォルトでRuntimeError例外を発生させます。
たとえば、上記のプログラムを次の形式に変更します。
classAuctionException(Exception): pass
classAuctionTest:
def __init__(self, init_price):
self.init_price = init_price
def bid(self, bid_price):
d =0.0try:
d =float(bid_price)
except Exception as e:
# ここでは、単に例外情報を印刷するだけです
print("例外を変換します:", e)
# カスタム例外を再度スローする
raise
if self.init_price d:
raise AuctionException("入札価格が開始価格よりも安いため、入札はできません!")
initPrice = d
def main():
at =AuctionTest(20.4)try:
at.bid("df")
except AuctionException as ae:
# 再度入札をキャッチ()メソッド内の例外、および例外の処理
print('main関数によってキャッチされた例外:', ae)main()
13行のコードからわかるように、プログラムは、exceptブロックのraiseステートメントを使用して例外を発生させます。その後、raiseステートメントは、exceptブロックによってキャッチされた例外を再度発生させます。プログラムを実行すると、次の出力が表示されます。
例外を変換しました:文字列をfloatに変換できませんでした: 'df'
main関数によってキャッチされた例外: <class ‘ValueError’
ナレッジポイントの補足:
デモレイズ使用量
try:
s = None
if s is None:
print "sは空のオブジェクトです"
raise NameError #NameError例外が発生した場合、次のコードは実行されません。
print len(s) #この文は実行されませんが、後の文はまだ実行されます
except TypeError:
print "空のオブジェクトには長さがありません"
s = None
if s is None:
raise NameError
print 'is here?' #使用しない場合は......このフォームを除いて、例外を直接スローすると、ここでは実行されません
トリガー例外
自分で例外をトリガーするためにraiseステートメントを使用できます
raiseの構文形式は次のとおりです。
raise [Exception [, args [, traceback]]]
ステートメントの例外は、例外のタイプ(たとえば、NameError)です。argsは、それ自体によって提供される例外パラメーターです。
最後のパラメーターはオプションであり(実際にはほとんど使用されません)、存在する場合は、例外オブジェクトを追跡します。 Python初心者のレイズの使用法を学ぶ方法については、この記事の終わりです。Pythonでのレイズの使用法の関連コンテンツについては、ZaLou.Cnで以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後、ZaLou.Cnをさらにサポートしていただければ幸いです。
Recommended Posts