ホームページ  >  記事  >  バックエンド開発  >  Python例外処理の概要

Python例外処理の概要

WBOY
WBOYオリジナル
2016-12-05 13:27:151019ブラウズ

最近、小さなプロジェクトをやっているとPythonの異常に遭遇することが多く、非常に頭を悩ませることになるので、次に困らないように異常を回避するための整理を以下に示します。

1.Python例外クラス

例外説明名前エラー宣言されていない変数にアクセスしようとしていますゼロディビジョンエラー約数は0です構文エラー文法エラーインデックスエラーシーケンス範囲外のインデックスキーエラー存在しない辞書キーを要求していますIOエラー入出力エラー (例: 読み取りたいファイルが存在しない)属性エラー不明なオブジェクトのプロパティにアクセスしようとしています値エラー int() 関数に文字を渡すなど、関数に渡されるパラメータの型が正しくありません

2. 例外をキャッチする

Python の完全な例外キャッチ ステートメントは次のようになります:

リーリー

うーん...複雑ではないですか?もちろん、例外をキャッチしたい場合は、else ステートメントを完全に破棄する必要はありません。また、finally ステートメントも必要ありません。 Final ステートメントはそのままにしておきます。え、気を失った?さて、一つずつ説明しましょう。

2.1 try...excel... ステートメント

Try_suite 言うまでもなく、これが例外をキャッチするために必要なコードであることは誰もが知っています。キーとなるのは、Except ステートメントです。try がコード セグメント try_suite で例外をキャプチャした後、Except によって処理されます。

Try...Except ステートメントの最も単純な形式は次のとおりです:

リーリー

上記のExcept節の後には例外や例外パラメータが続かないので、tryがどのような例外をキャッチしても、Exception節の例外ブロックに渡されて処理されます。特定の例外を処理したい場合、たとえば、ゼロによる除算の例外だけを処理し、他の例外が発生した場合は、それらの例外を処理せずにスローする場合はどうすればよいでしょうか。このとき、Exception 句に例外パラメータを渡す必要があります。 ExceptionN は、Exception 節に指定する例外クラスです (例外クラスの表を参照してください)。これは、このタイプの例外が捕捉された場合、この例外節によって処理されることを意味します。例:

リーリー

例:

リーリー

見て、実際に ZeroDivisionError 例外をキャッチしました。では、複数の例外をキャッチして処理したい場合はどうすればよいでしょうか?方法は 2 つあり、1 つは複数の例外クラス パラメータを 1 つの例外句に渡す方法、もう 1 つは複数の例外句を記述し、各句で処理する例外クラス パラメータを渡す方法です。これら 2 つの用途は組み合わせて使用​​することもできます。例を挙げてみましょう。

リーリー

上記の例は誰でも一目で理解できるので、これ以上は説明しません。ただし、Except が 1 つの例外、複数の例外、さらにはすべての例外を処理できることを誰もが理解している必要があります。

例外節の後の引数が何であるかを説明していないことに気づいたかもしれません?心配しないで、聞いてください。この引数は実際には例外クラスのインスタンスであり (インスタンスが何であるか知らないとは言わないでください)、例外コードからの診断情報が含まれています。つまり、例外をキャッチすると、例外クラスのインスタンスを通じて例外に関する詳細情報を取得できます。例:

リーリー

上記の例では、ゼロ除算例外をキャッチしましたが、何もしませんでした。その理由は、型を通じて確認できる例外クラス ZeroDivisionError のインスタンスです。

2.2 try...excel...else ステートメント

それでは、この else ステートメントについて説明しましょう。 Python には、for 条件文やループなど、else の特殊な使用法が数多くあります。これを try ステートメントに入れても、その効果はほぼ同じです。例外が検出されない場合、else ステートメントが実行されます。理解を深めるために例を挙げてみましょう:

リーリー

2.3 最後にステートメント

finally 句は、例外が検出されたかどうかに関係なく実行されるコードです。 Except 句と else 句を捨てて、try...finally を単独で使用することも、excel などと組み合わせて使用​​することもできます。

例えば2.2の例では、他にキャッチできない例外が発生してプログラムが異常終了した場合、ファイルfは正常にクローズされません。これは望んでいる結果ではありませんが、finally 文の中に f.close 文を入れると、例外が発生してもファイルが正常に閉じられるようになると思います

コードをコピー

リーリー

3. 例外を処理するための 2 つの特別で便利なメソッド

3.1 アサート

まず構文を見てみましょう:

式をアサート[,理由]

ここで、assert はアサーションのキーワードです。このステートメントを実行すると、最初に式が評価され、式が true でない場合は何も行われず、例外がスローされます。理由は、前に説明した例外クラスのインスタンスと同じです。知りませんか?関係ないから、例をあげてよ!最も実用的です!

リーリー

assert後の式がtrueの場合は何も行われず、trueでない場合はAssertionErro例外がスローされ、渡した文字列が例外クラスのインスタンスの固有情報として存在することがわかります。 。実際、アサート例外は try ブロックでもキャッチできます:

リーリー

3.2. コンテキスト管理(ステートメントあり)

共有リソース (ファイル、データなど) の一意の割り当てを確保するためだけに try、excel、finally のコードを使用し、タスクの終了後に解放する場合は、幸運です。この with ステートメントを使用すると、try、excel、finally から解放されます。構文は次のとおりです:

context_expr [as var]を使用:
with_スイート

分かりませんか?それは普通のことです、例を挙げてください!

リーリー

上面这几行代码干了什么?

    (1)打开文件/root/test.py

    (2)将文件对象赋值给  f

    (3)将文件所有行输出

    (4)无论代码中是否出现异常,Python都会为我们关闭这个文件,我们不需要关心这些细节。

    这下,是不是明白了,使用with语句来使用这些共享资源,我们不用担心会因为某种原因而没有释放他。但并不是所有的对象都可以使用with语句,只有支持上下文管理协议(context management protocol)的对象才可以,那哪些对象支持该协议呢?如下表 

file

decimal.Contex 

thread.LockType 

threading.Lock 

threading.RLock 

threading.Condition 

threading.Semaphore 

threading.BoundedSemaphore

至于什么是上下文管理协议,如果你不只关心怎么用with,以及哪些对象可以使用with,那么我们就不比太关心这个问题

4.抛出异常(raise)

如果我们想要在自己编写的程序中主动抛出异常,该怎么办呢?raise语句可以帮助我们达到目的。其基本语法如下:

raise [SomeException [, args [,traceback]] 
第一个参数,SomeException必须是一个异常类,或异常类的实例

第二个参数是传递给SomeException的参数,必须是一个元组。这个参数用来传递关于这个异常的有用信息。

第三个参数traceback很少用,主要是用来提供一个跟中记录对(traceback)
下面我们就来列举几个 例子:

>>> raise NameError
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError
>>> raise NameError() #异常类的实例
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError
>>> raise NameError,("There is a name error","in test.py")
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
>>> raise NameError("There is a name error","in test.py") #注意跟上面一个例子的区别
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError: ('There is a name error', 'in test.py')
>>> raise NameError,NameError("There is a name error","in test.py") #注意跟上面一个例子的区别
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError: ('There is a name error', 'in test.py')

 其实,我们最常用的还是,只传入第一个参数用来指出异常类型,最多再传入一个元组,用来给出说明信息。如上面第三个例子。

5.异常和sys模块

另一种获取异常信息的途径是通过sys模块中的exc_info()函数。该函数回返回一个三元组:(异常类,异常类的实例,跟中记录对象)

>>> try:
...   1/0
... except:
...   import sys
...   tuple = sys.exc_info()
... 
>>> print tuple
(<type 'exceptions.ZeroDivisionError'>, ZeroDivisionError('integer division or modulo by zero',), <traceback object at 0x7f538a318b48>)
>>> for i in tuple:
...   print i
... 
<type 'exceptions.ZeroDivisionError'> #异常类    
integer division or modulo by zero #异常类的实例
<traceback object at 0x7f538a318b48> #跟踪记录对象

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。