python try except python handling exception with examples
このチュートリアルでは、プログラミング例を使用して、TryExceptブロックを使用したPythonでの例外処理について説明します。
2つのエラータイプにより、Pythonプログラムが突然停止する可能性があります。 構文エラー 、および 例外 。このチュートリアルでは、いくつかの重要なトピックの下で2番目のエラータイプ(例外)について説明します。
Macで7zを開く方法
次のようなアプリケーションで例外を処理することで、多くのメリットが得られます。
- 堅牢なアプリケーションを作成します。
- クリーンでエラーのないコードを作成します。
=> 独占的なPythonトレーニングチュートリアルシリーズについては、こちらをご覧ください
学習内容:
Pythonは例外を試す
良いニュースの1つは、Pythonには、コードのエラーをキャッチするための多数の組み込み例外があることです。また、組み込みの例外がどれもニーズに合わない場合に、カスタム例外を作成する機会を与えてくれます。
例外とは
では、Pythonの例外は何ですか?簡単に言うと、Pythonインタープリターが無効なコードを実行しようとすると例外が発生し、そのような例外が処理されない場合は、プログラムの命令の通常のフローが中断され、トレースバックが出力されます。
無効なコードを作成して、Pythonインタープリターがどのように応答するかを見てみましょう。
Pythonシェルを開き、次のコードを実行します。
>>> 50/0
これは、プログラミングで最も一般的なエラーの1つです。上記のコードは数値を除算しようとします 50 沿って 0 (ゼロ)。 Pythonインタープリターはこれを無効な操作と見なし、 ZeroDivisionError 、プログラムを中断し、トレースバックを出力します。
はっきりとわかります ZeroDivisionError 提起された例外です。数値をゼロで割るのはクールではないことを私たちに伝えるのは、確かにPython独自の方法です。 JavaScriptのような他の言語では、これはエラーではありません。そしてpythonはこの慣行を厳しく禁じています。
また、これは単なる例外オブジェクトであり、Pythonにはそのようなオブジェクトが多数組み込まれていることを知っておくことが重要です。このPythonの公式をチェックしてください ドキュメンテーション すべてのPython組み込み例外を確認します。
トレースバックを理解する
例外の処理に取り掛かる前に、例外が処理されない場合に正確に何が起こるか、そしてPythonがエラーについて通知するために最善を尽くす方法を理解することが役立つと思います。
Pythonでエラーが発生すると、例外が発生します。この例外が処理されない場合、トレースバックと呼ばれる情報が生成されます。では、このトレースバックにはどのような情報が含まれていますか?
を含む:
- どの例外が発生したか、およびこの例外が発生する前に何が起こったかを示すエラーメッセージ。
- このエラーの原因となったコードのさまざまな行番号。エラーは、と呼ばれる一連の関数呼び出しによって引き起こされる可能性があります コールスタック これについては後でここで説明します。
少し紛らわしいですが、次の例が私たちの理解にもっと光をもたらすことを約束します。
上記の50を0で割って印刷されたトレースバックを思い出してください。トレースバックには、次の情報が含まれていることがわかります。
- ファイル「」:これは、このコードがコンソール端末から実行されたことを示しています。
- 1行目:これは、この行番号でエラーが発生したことを示しています。
- ZeroDivisionError: による除算 ゼロ: どの例外が発生し、何が原因であるかがわかります。
別の例を試してみて、おそらくどのように コールスタック のように見えます。エディターを開き、以下のコードを入力して、名前を付けて保存します tracebackExp .py
def stack1(numb): # 1 div = 0 # 2 stack2(numb, div) # 3 def stack2(numb, div): # 5 compute = numb/div # 6 print(compute) # 7 if __name__ == '__main__': # 9 numb = 5 # 10 stack1(numb) # 11
このファイルが見つかったディレクトリでターミナルを開き、実行します。
python tracebackExp.py
次のトレースバックが表示されます。
上記のトレースバックは紛らわしいように見えるかもしれませんが、実際にはそうではありません。 Pythonistasは、トレースバックを読み取るための最良の方法を考え出しました。 一気飲み 。それでは、この知恵を使用して、このトレースバックが提供するものを理解してみましょう。
- 一番下に、発生した例外と、発生した理由が表示されます。
- 上に移動すると、ファイル名が取得されます tracebackExp このエラーが発生した.py、このエラーの原因となった計算compute = numb / div、関数stack2、およびこの計算が実行されたリンク番号の6行目。
- 上に移動すると、stack2関数が行番号3の関数stack1で呼び出されたことがわかります。
- 一番上に移動すると、関数stack1が行番号11で呼び出されたことがわかります。< モジュール >は、実行されているのはファイルであることを示しています。
一般的なPythonの例外
Pythonライブラリは、非常に多くの組み込み例外を定義しています。 Pythonドキュメントを確認するか、組み込みの呼び出しを行うことができます 地元 ()は以下のように機能します:
>>> dir(locals()('__builtins__'))
これらすべての例外に対処しようとはしませんが、遭遇する可能性のあるいくつかの一般的な例外を確認します。
#1)TypeError
不適切なタイプのオブジェクトに操作または関数が適用された場合に発生します。
例1
以下のプログラムを検討してください。被除数と除数を取り込んだ後、被除数を除数で除算した結果を計算して出力します。
def compute_division(): dividend = int(input('Enter the dividend: ')) # cast string to int divisor = input('Enter the divisor: ') # no casting # Compute division result = dividend/divisor # print result print('The result of {}/{} is: {}'.format(dividend, divisor, result)) if __name__ == '__main__': result = compute_division()
被除数と除数の値をユーザーに要求しましたが、除数の文字列値を整数にキャストするのを忘れています。したがって、配当の型はinteger( int )および除数の型はstring( p )。次に、 TypeError 除算演算子(/)は文字列を操作しないためです。
Pythonとは異なり、Javascriptには、オペランドの型が異なる場合に、基本的にオペランドの型の1つを他のオペランドの型と同等の値に変換する型強制があります。
#2)ValueError
これは、操作または関数が正しい型であるが不適切な値の引数を受け取った場合に発生します。
例2
で私たちのプログラムを検討してください 例1 上記。
ユーザーが「3a」のような被除数の英数字値を入力すると、プログラムはValueError例外を発生させます。これは、Pythonが int() メソッドは任意の数値または文字列を受け取り、整数オブジェクトを返します。文字列値に文字や数値以外の値を含めることはできません。
#3)AttributeError
この例外は、存在しない属性を割り当てまたは参照しているときに発生します。
例3
以下のプログラムを検討してください。数値を取り込んで、を使用して平方根を計算します。 Python数学モジュール
import math # import math library to gain access to its code def compute_square_root(number): # compute the square root using the math library result = math.sqr(number) return result if __name__ == '__main__': # get input to compute from user number = int(input('Compute Square root of: ')) # call function to compute square root
ユーザーが数値を入力すると、プログラムは数学モジュールの関数を使用してその平方根を計算しようとしますが、ここではエラーが発生しました。 sqrtの代わりに、数学モジュールに存在しないsqrを誤って入力しました。
そのため、存在しない属性sqrを参照しようとして、例外AttributeErrorが発生しました。私たちのほとんどは、この種の間違いをたくさん犯します。だから、あなたは一人ではありません。
TryExceptを使用した例外の処理
プログラマーとして、私たちのほとんどが時間を費やす1つのことは、回復力のある堅牢なコードを書くことです。いくつかのエラーのために壊れないコード。 Pythonでは、ステートメントをaで囲むことでこれを実現できます。 試してみてください - を除いて ステートメント。
PythonTry-Exceptステートメント
try-exceptステートメントの構造は次のとおりです。
try: #your code goes here except '''Specify exception type(s) here''': #handle exception here
コードをで囲みましょう tracebackExp try-exceptステートメント内の.py。
def stack1(numb): # 1 div = 0 # 2 stack2(numb, div) # 3 def stack2(numb, div): # 5 try: # 6 compute = numb/div # 7 print(compute) # 8 except ZeroDivisionError as zde: # 9 print(zde) # 10 if __name__ == '__main__': # 12 numb = 5 # 13 stack1(numb) # 14 print('program continuous') # 15
このコードを実行すると、出力が生成されます
これがtry-exceptステートメントの仕組みです。 Pythonはtryブロックのコードを実行します 7〜8行目 。無効なコードが見つからない場合は、exceptブロックのコード 10行目 スキップされ、実行が続行されます。
ただし、無効なコードが見つかった場合、実行はtryブロックですぐに停止し、発生した例外が、exceptステートメントで指定したものと一致するかどうかを確認します。 9行目 。一致する場合、exceptブロックが実行されて続行されます。そうでない場合、プログラムは中断します。
try-blockには通常、exception-blockが例外をキャッチして処理している間に、例外を発生させる可能性のあるコードが含まれています。
を除く複数の例外の処理
単一の「例外」または複数の「例外」のいずれかで複数の例外を処理できます。それはすべて、各例外をどのように処理するかによって異なります。
#1)単一の例外で複数の例外を処理する
try: #your code goes here except(Exception1(, Exception2(,...ExceptionN)))): #handle exception here
このメソッドは、コードで異なる例外が発生する可能性があり、それぞれの場合に同じアクションを実行する必要がある場合に使用されます。したがって、Pythonインタープリターが一致するものを見つけると、exceptブロックに記述されたコードが実行されます。
以下のPythonコードの例を考えてみましょう
def get_fraction(value, idx): arr = (4,5,2,0) # a list of numbers idx_value = arr(idx) # if idx is > arr length, IndexError will be raised value/idx_value # if idx_value == 0, ZeroDivisionError will be raised if __name__ =='__main__': # set 'value' and 'idx' value = 54 idx = 3 # call function in a try-except statement. try: result = get_fraction(value, idx) print('Fraction is ', result) except (IndexError, ZeroDivisionError) as ex: print(ex)
ここで発生する可能性のある2つの例外があります。 ZeroDivisionError そして IndexError 。これらの例外のいずれかが発生した場合、exceptブロックが実行されます。
上記のコードでは、idx = 3なので、idx_ 値 0になり、 値 / idx_ 値 ZeroDivisionErrorを発生させます
#2)複数の例外を含む複数の例外の処理
try: #your code goes here except Exception1: #handle exception1 here except Exception2: #handle exception2 here except ExceptionN: #handle exceptionN here
各例外を個別に処理したい場合は、これがその方法です。
以下のPythonコードの例を考えてみましょう
def get_fraction(value, idx): arr = (4,5,2,0) # a list of numbers idx_value = arr(idx) # if idx is > arr length, IndexError will be raised value/idx_value # if idx_value == 0, ZeroDivisionError will be raised if __name__ =='__main__': # set 'value' and 'idx' value = 54 idx = 5 # call function in a try-excepts statement. try: result = get_fraction(value, idx) print('Fraction is ', result) except IndexError: print('idx of {} is out of range'.format(idx)) except ZeroDivisionError: print('arr({}) is 0. Hence, can't divide by zero'.format(idx)) except Exception as ex: print(ex) print('Not sure what happened so not safe to continue, app will be interrupted') raise ex
ここで、最後のexceptステートメントでExceptionが使用されていることがわかります。これは、例外オブジェクトExceptionがすべての例外と一致するためです。このため、Pythonは他の例外ハンドラーが一致するとチェックを停止するため、常に最後にする必要があります。
上記のコードでは、 idx = 5 、したがって arr (idx) 上げる IndexError なぜなら idx リストの長さよりも大きい arr
また、アプリケーションによって発生した例外が安全に実行を継続できるかどうかもわかりません。そのため、予期しない例外をキャッチするためのタイプExceptionがあります。次に、ユーザーに通知し、同じ例外を発生させてアプリケーションを中断します。
他のステートメントを試してください
これは オプション機能 例外処理の機能を備えており、エラーが発生しなかったときに実行するコードを追加できます。エラーが発生した場合、このelse-blockは実行されません。
以下のPythonコードの例を検討し、エディターを開いて、コードをelseTry.pyとして保存します。
def fraction_of_one(divisor): value = 1/divisor # if divisor is zero, ZeroDivisionError will be raised return value if __name__ == '__main__': while True: try: # Get input from the user. # if input is not a valid argument for int(), ValueError will be raised divisor = int(input('Enter a divisor: ')) # call our function to compute the fraction value = fraction_of_one(divisor) except (ValueError, ZeroDivisionError): print('Input can't be zero and should be a valid literal for int(). Please, try again!') else: print('Value: ', value) break
ユーザーから入力を取得し、それを使用して1を除算します。ここでは2つの例外が考えられます。無効なユーザー入力により、 ValueError と ゼロ(0) これが原因になります ZeroDivisionError 。私たちのexceptステートメントはこれらのエラーを処理します。
ここで、の値を出力します。 値 。 else-blockは、tryブロックがエラーなしで実行された場合にのみ出力されるようにします。 try-blockでエラーが発生した場合、これは重要です。 値 未定義になります。したがって、それにアクセスすると別のエラーが発生します。
上記のコードをPythonelseTry.pyで実行します
上記の出力は、最初の入力に対して入力したことを示しています 0 ENTERを押します。私たちの除数が0を受け取ったので、1 /除数が上がりました zeroDivisionError 。 2番目の入力はkでしたが、これは int ()、したがって例外 ValueError 上げられます。
しかし、最後の入力は9でした。これは有効であり、その結果、「 値 」は0.1111111111111111として印刷されます
最後に試してくださいステートメント
これも オプション機能 例外処理の機能であり、例外ハンドラーで何が起こっても常に実行されます。
あれは:
- 例外が発生するかどうか
- 他のブロックで「リターン」が呼び出された場合でも。
- スクリプトが他のブロックで終了した場合でも
したがって、すべての状況で実行したいコードがある場合、finally-blockが私たちの役目です。このブロックは主に、ファイルを閉じるなどのクリーンアップに使用されます。
以下のPythonコードの例を考えてみましょう
def readFile(file_path): try: openFile = open(file_path,'r') # Open a file as read-only print(openFile.readline()) # Read first line of file content except FileNotFoundError as ex: print(ex) finally: print('Cleaning...') openFile.close() if __name__ == '__main__': filePath = './text.txt' readFile(filePath)
このコードは、現在のディレクトリにあるtext.txtファイルを開いて読み取ろうとします。ファイルが存在する場合、プログラムはファイルの最初の行を出力し、finally-blockが実行されてファイルが閉じます。
このプログラムファイルがあり、Helloが含まれているディレクトリにtext.txtというファイルがあるとします。プログラムを実行すると、出力が得られます
この例は、finally-blockでファイルを閉じるときに発生する可能性のある小さな問題に対処したかったため、意図的に選択されました。
ファイルが存在しない場合、例外 FileNotFoundError が発生し、変数 openFile 定義されず、ファイルオブジェクトにもなりません。したがって、finally-blockで閉じようとすると、例外が発生します UnboundLocalError これはのサブクラスです NameError 。
これは基本的に、変数を参照しようとしていることを示しています openFile 割り当てられる前。
ここでの小さなトリックは、finallyブロック内で例外ハンドラーを使用することです。
def readFile(file_path): try: openFile = open(file_path,'r') # Open a file as read-only print(openFile.readline()) # Read first line of file content except FileNotFoundError as ex: print(ex) finally: try: print('Cleaning...') openFile.close() except: # catches all exceptions pass # Ignore this error because we don't care. if __name__ == '__main__': filePath = './text.txt' readFile(filePath)
try-blockでFileNotFoundErrorが発生した場合、次の出力が得られます
例外を発生させる
Pythonの例外に関する良いニュースの1つは、意図的に例外を発生させることができるということです。例外は 声明を上げる 。
raiseステートメントの構文は次のとおりです。
raise (ExceptionName((*args: Object)))
ターミナルを開き、から例外オブジェクトを発生させます Pythonに組み込まれた例外。 例えば、 ZeroDivisionErrorを発生させた場合:
>>> raise ZeroDivisionError('Can't divide by zero')
トレースバックを取得します。
では、なぜ例外を発生させることが重要なのでしょうか。
- カスタム例外を処理する場合。
- 健全性チェック中。
カスタム例外クラス
カスタム例外は、ニーズに固有のエラーを処理するために作成する例外です。秘訣は、オブジェクトから派生するクラスを定義することです 例外 、次に、raiseステートメントを使用して例外クラスを発生させます。
ユーザー入力をチェックし、入力値が負でないことを確認するとします(健全性チェック)。もちろん、Python例外ValueErrorを発生させることもできますが、次のような具体的でわかりやすい名前を付けてエラーをカスタマイズしたいと思います。 InputIsNegativeError 。ただし、この例外はPythonに組み込まれている例外ではありません。
したがって、最初に、Exceptionから派生する基本クラスを作成します。
class CustomError(Exception): 'Base class exception for all exceptions of this module' pass
次に、基本クラスを継承し、特定のエラーを処理する例外クラスを作成します。
class InputIsNegativeError(CustomError): '''Raised when User enters a negative value''' pass
これをテストしてみましょう
try: value = int(input()) if value <0: raise InputIsNegativeError # Raise exception if value is negative except InputIsNegativeError: # catch and handle exception print('Input value shouldn't be negative')
上記のコードはユーザー入力を要求し、それが負であるかどうかを確認します。 trueの場合、カスタム例外InputIsNegativeErrorが発生します。これは、後でexceptステートメントでキャッチされます。
以下は完全なコードです:
class CustomError(Exception): 'Base class exception for all exceptions of this module' pass class InputIsNegativeError(CustomError): '''Raised when User enters a negative value''' pass if __name__ == '__main__': try: value = int(input('Input a number: ')) if value <0: raise InputIsNegativeError # Raise exception if value is negative except InputIsNegativeError: # catch and handle exception print('Input value shouldn't be negative')
入力値が-1のような負の数の場合、出力は次のようになります。
チェックしてください Pythonドキュメント Pythonカスタム例外の詳細については。
よくある質問
Q#1)Pythonはどのように例外を処理しますか?
回答: Pythonは、を使用して例外を処理します try-exceptステートメント 。例外を発生させる可能性のあるコードは、 ブロックしてみてください 一方、 ブロックを除く 例外が発生した場合にそれを処理するコードを保持します。
Q#2)Pythonで例外が発生する原因は何ですか?
回答: Pythonインタープリターが無効なコードを検出すると、例外が発生します。これは、予期しないことが発生したことをPython独自の方法で通知します。を使用して意図的に例外を発生させることもできます 声明を上げる 。
Q#3)Pythonは複数の例外をどのように処理しますか?
回答: Pythonは、単一の例外ブロックまたは複数の例外ブロックのいずれかを使用して、複数の例外を処理します。
単一のブロックの場合、例外はタプルとして渡されます。 を除いて (Exception1、Exception2、..、ExceptionN)およびPythonは、右から左への一致をチェックします。この場合、例外ごとに同じアクションが実行されます。
すべての例外をキャッチする別の方法は、exceptキーワードの後に例外の名前を省略することです。
except: # handle all exceptions here
2番目の方法は、例外ごとにexceptブロックを使用することです。
except Exception1: # code to handle Exception1 goes here except Exception2: # code to handle Exception2 goes here except ExceptionN: # code to handle ExceptionN goes here
このようにして、例外ごとに個別のアクションを実行できます。
Q#4)Pythonで例外処理が重要なのはなぜですか?
回答: Pythonで例外を処理する利点は、堅牢でクリーンでエラーのないアプリケーションを作成できることです。一部のエラーが原因で本番コードがクラッシュすることは望ましくないため、エラーを処理してアプリケーションを稼働させ続けます。
Q#5)Pythonの例外をどのように無視しますか?
回答: Pythonで例外を無視するには、 パス 例外ブロックのキーワード。 ValueError例外を無視したいとします。私たちはこのようにします:
except ValueError: pass
自分が何をしているのかわからない限り、例外を無視するのは悪い習慣です。少なくとも、すべての潜在的なエラーについてユーザーに通知してください。
結論
このチュートリアルでは、以下について説明しました。Python例外、トレースバック。で例外を処理する方法 試してみてください / を除いて / そうしないと / 最後に ブロック、方法 上げる 例外、そして最後に独自のカスタム例外を作成する方法。
読んでくれてありがとう!
=> Pythonを最初から学ぶには、こちらにアクセスしてください。