ホームページ >バックエンド開発 >Python チュートリアル >Python 2.7 基本チュートリアル: エラーと例外

Python 2.7 基本チュートリアル: エラーと例外

黄舟
黄舟オリジナル
2016-12-24 17:13:591732ブラウズ

.. _tut-errors:

====================================

エラーと例外エラーと例外

==================================

これまで、エラー メッセージはこれ以上ありませんでした。ただし、例を試したことがあるなら、おそらくいくつか見たことがあるでしょう。*構文エラー* と *例外* という、(少なくとも) 2 つの区別可能なエラーがあります。

これ以上の説明はありません。メッセージですが、

が実験した例の中でいくつかのメッセージに遭遇した可能性があります。 Python には (少なくとも) 2 種類のエラーがあります: *構文エラー* と *例外*

.. _tut-syntaxerrors:

構文エラー 構文エラー

========================

構文エラー、解析エラーとも呼ばれますおそらく、Python を学習中に最も一般的な種類の

苦情です。

文法エラー (解釈エラーとも呼ばれます) は、Python を学習中に最も一般的な種類の

苦情かもしれません。 :

>>> while True print 'Hello world'

'File ""、line 1、in ?

' while True print 'Hello world'

' ' ' ^

' SyntaxError: 無効な構文

パーサーは問題のある行を繰り返し、エラーが検出された行の最も古い点を指す小さな「矢印」を表示します

エラーの原因は

です。矢印の*前にあるトークン:

の例では、キーワード:keyword:`print`でエラーが検出されます。これは、その前にコロン

(``':'``)が欠落しているためです。行番号が出力されるので、入力がスクリプトからのものである場合にどこを見るべきかがわかります

パーサーはエラーのある行を繰り返し、その行で見つかった最も早いエラーに小さな「矢印」を表示します。エラー

(少なくとも検出されたエラー) は、矢印が指す場所*で発生します。この例のエラーは、キーワード

:keyword:`print` の前にコロン ( ``':'`` ) が欠落しているために表示されます。ファイル名と行番号も表示されるので、

どのスクリプトからエラーが発生し、どこにエラーがあるのか​​を知ることができます。

.. _tut-Exceptions:

Exceptions

==========

ステートメントや式が構文的に正しい場合でも、それを実行しようとすると

エラーが発生する可能性があります実行中に検出されたエラー

は *例外* と呼ばれ、無条件に致命的というわけではありません。ただし、ほとんどの例外は

プログラムでは処理されず、次のようなエラー メッセージが表示されます。ここに示されています:

ステートメントが文法的に完全に正しい場合でも、それを実行しようとするとエラーが発生する可能性があります。プログラムの実行中に検出されたエラーは例外と呼ばれ、通常は致命的な問題を引き起こすことはありません。Python プログラムでエラーを制御する方法はすぐに学びます。ほとんどの例外はプログラムによって処理されませんが、エラー メッセージが表示されます::

>>> 10 * (1/0)

トレースバック (最新の呼び出し最後):

ファイル "< ;stdin> ;"、1 行目、?

ZeroDivisionError: 整数除算またはゼロによる剰余

>>> 4 + スパム*3

トレースバック (最新の呼び出し最後の):

ファイル "

NameError: 名前 'spam' が定義されていません

>>> '2' + 2

トレースバック (最新の呼び出し最後):

ファイル " "、 1 行目、?

TypeError: 'str' と 'int' オブジェクトを連結できません

エラー メッセージの最後の行は、例外がさまざまな型で発生することを示しており、その型はメッセージの一部として出力されます。 : のタイプ

例は、:exc:`ZeroDivisionError`、:exc:`NameError`、および :exc:`TypeError` です。

例外タイプとして出力される文字列は、組み込み例外の名前です

これはすべての組み込み例外に当てはまりますが、ユーザー定義の例外には当てはまりません

(これは便利な規則ですが)。

エラー メッセージの最後の行は、どのようなエラーが発生したかを示します。例外にもさまざまなタイプがあり、例外タイプはエラー メッセージの一部として表示されます。例の例外は、ゼロ除算エラー ( :exc:`ZeroDivisionError` )、ネーミング エラー ( :exc:`NameError`)、およびタイプ

です。

エラー ( :exc:`TypeError` )。エラー情報を出力するとき、例外タイプは例外の組み込み名として使用されます

ショー。これはすべての組み込み例外に当てはまりますが、ユーザー定義の例外には必ずしも当てはまりません (ただし、これは便利な規則です)。標準例外名は組み込みの識別子です (予約されたキーワードはありません)。

行の残りの部分は、例外の種類とその原因

に基づいた詳細を提供します。

行の最後の部分は、例外の種類の詳細な説明です。つまり、その内容は例外の種類によって異なります。

エラー メッセージの前の部分には、例外

が発生したコンテキストがスタック トレースバックの形式で表示されます。ただし、ソース行をリストするスタック

は表示されません。

標準入力。

エラー メッセージの前半には、例外が発生した場所がスタックの形式でリストされます。通常、ソース コード行はスタックにリストされますが、標準入力からのソース コードは表示されません。

:ref:`bltin-Exceptions` は、組み込み例外とその意味をリストします。

:ref:`bltin-Exceptions` は、組み込み例外とその意味をリストします。

.. _tut-handling:

例外処理 例外を制御する

============================

選択した例外を処理するプログラムを作成します

次の例を見てください。この例では、有効な整数が入力されるまでユーザーに入力を求めます

が、ユーザーは (:kbd:`Control-C` または を使用して) プログラムを中断できます。

オペレーティング システムがサポートするもの); ユーザー生成の割り込み

は、:exc:`KeyboardInterrupt` 例外を発生させることによって通知されることに注意してください。:

既知の例外を制御するためにプログラムを作成することもできます。以下の例を参照してください。この例では、有効な整数が得られるまでユーザーに情報を入力する必要があり、ユーザーは (:kbd:`Control-C` またはオペレーティング システムでサポートされているその他の操作を使用して) プログラムを中断できます。必須 ユーザー生成の割り込みは

:exc:`KeyboardInterrupt` 例外をスローすることに注意してください。 ::

>>> while True:

... try:

... x = int(raw_input("数字を入力してください: "))

... Break

.. . ValueError:

を除く ... print "おっと! 有効な番号ではありませんでした。もう一度試してください..."

...

:keyword:`try` ステートメントは次のように機能します。

:keyword:` try` ステートメントは次のように機能します。

* まず、*try 句* (:keyword:`try` と

:keyword:`excel` キーワードの間のステートメント) が実行されます。 :keyword:`try` と : の間の部分。キーワード:`キーワードを除く)。

* 例外が発生しない場合、*excel 節* はスキップされ、

:keyword:`try` ステートメントの実行が終了します。

例外が発生しない場合、*excel 節* はスキップされ、:keyword の実行が完了します。 :`try` ステートメントの実行後は無視されます。

* try 句の実行中に例外が発生した場合、

句の残りの部分はスキップされ、そのタイプが :keyword:`excel` キーワードに基づいて指定された例外と一致する場合は、Except 句が実行されます。そして、:keyword:`try` ステートメントの後に実行

が続行されます。

try 句の実行中に例外が発生した場合、句の残りの部分は無視されます。

例外が :keyword:`excel` キーワードの後に​​指定された例外タイプと一致する場合、対応する else 句

が実行されます。次に、:keyword:`try` ステートメントの後のコードの実行を続けます。

* 例外

節で指定された例外と一致しない例外が発生した場合、その例外は外側の :keyword:`try` ステートメントに渡されます。ハンドラーが見つからない場合、それは *未処理の例外* となります。実行は上記の

のようなメッセージで停止します。

例外が発生し、Exception 節に一致する分岐がない場合は、上位レベルの:keyword:`try` ステートメントに渡されます。最終的に対応する処理文が見つからない場合は、「未処理例外」となり、プログラムを終了し、プロンプトメッセージを表示します。

:keyword:`try` ステートメントには、異なる例外の

ハンドラーを指定するために、複数の例外句を含めることができます。

ハンドラーは、対応する try 句で発生する例外のみを処理し、処理しません。

同じ :keyword:`try` ステートメントの他のハンドラーでは、Except 句で複数の例外を括弧で囲まれたタプルとして指定することができます。たとえば、:

:keyword:`try` ステートメントには、次のように指定する複数のException 句が含まれる場合があります。それぞれ異なる例外の処理。最大でも 1 つのブランチのみが実行されます。例外ハンドラーは、対応する try 句のみを処理します。

同じ :keyword:`try` ステートメント内で発生した例外、他の句で発生した例外は処理されません

。例::

... 例外 (RuntimeError, TypeError, NameError):

... pass

最後の例外句では、例外名を省略できます。ワイルドカードとして機能します

この方法では実際のプログラミング エラーを簡単にマスクできるため、細心の注意を払って使用してください

また、エラー メッセージを出力してから例外を再発生させるために使用することもできます

(呼び出し元も同様に例外を処理できるようにします):

最後の else 句では例外名を省略し、ワイルドカードとして使用できます。この方法は、実際のプログラム エラーを隠して発見できなくなる可能性があるため、慎重に使用してください。また、エラー情報の行を出力し、例外を再スローするために使用することもできます (これにより、呼び出し元が例外をより適切に処理できるようになります)::

import sys

try:

f = open('myfile.txt')

s = f.readline()

i = int(s.strip())

ただし、IOError as (errno, strerror):

print "I/O エラー({0}): {1}" .format(errno, strerror) 例外 ValueError:

print "データを整数に変換できませんでした。" 例外:

print "予期しないエラー:", sys.exc_info()[0]

:keyword:`try` ... :keyword:`excel` ステートメントにはオプションの *else

節* があり、これが存在する場合は、すべての else 節の後に続く必要があります。これは、try 節が例外を発生させない場合に実行する必要がある

コードに役立ちます。例外。For

example:

:keyword:`try` ... :keyword:`excel` ステートメントには *else 節* を含めることができます。

この節はすべての else 節の後にのみ出現します。 try ステートメントが例外をスローせず、一部のコードを実行する必要がある場合は、

句を使用できます。例::

for arg in sys.argv[1:]:

try:

f = open(arg, 'r') IOError:

print 'cannot open', arg

else:

print arg, 'has', len(f.readlines()), ' :keyword:`try` 句は、誤って例外をキャッチすることを避けるためです

これは、:keyword: で保護されているコードによって発生したものではありません。 `try` ...

:keyword:`例外` ステートメント

:keyword:`else` 節を使用することは、:keyword:`try` 節にコードを追加するよりも優れています。これは、:keyword:` を回避できるためです。 try` ... :keyword:`例外` 予期しない偶発的なインターセプト 保護するコードによってスローされる例外。

例外が発生すると、

例外の *引数* とも呼ばれる関連する値が存在する場合があります。引数の存在と型は、

例外の型によって異なります。例外の *パラメータ* として存在する補助値。このパラメータが存在するかどうか、および

の型は例外のタイプによって異なります。

Except 句では、例外名 (またはタプル) の後に変数を指定できます。

その変数は、

``instance.args`` に格納された引数とともに例外インスタンスにバインドされます。便宜上、例外インスタンスは以下を定義します。

:meth:`__str__` なので、

``.args`` を参照することなく、引数を直接出力できます。

例外名 (リスト) の後に、Exception 句の変数を指定することもできます。この変数は例外インスタンスにバインドされ、instance.args の引数に格納されます。便宜上、例外インスタンス

は :meth:`__str__` を定義し、

``.args`` を参照せずに印刷パラメータに直接アクセスできるようにします。

例外を発生させる前にまず例外をインスタンス化し、必要に応じてそれに属性を追加することもできます:

この方法はお勧めできません。代わりに、より良いアプローチは、パラメーターを例外 (または、複数の

パラメーターを渡したい場合はタプル) に渡し、それをメッセージ プロパティにバインドすることです。例外が発生すると、スローする前に指定されたすべてのプロパティを

バインドします。 ::

>>> try:

... Exception('spam', 'eggs') を発生させる

... inst:

としての例外を除く ... print type(inst) #例外インスタンス

... print inst.args # .args

に格納されている引数

... 印刷インストprint ' y =', y

...

('スパム', '卵')

('スパム', '卵')

x = スパム

y = 卵

例外に引数がある場合、それはハンドルされない例外のメッセージ

の最後の部分 (「詳細」) として出力されます。

ハンドルされない例外の場合、引数があります。これは、エラー メッセージ

(「詳細」) の最後の部分として出力されます。

例外ハンドラーは、例外が

try句で即座に発生した場合にのみ処理するのではなく、try句で(間接的にであっても)呼び出される関数内で例外が発生した場合にも処理します。例:

例外ハンドラ ではありません。 try 句で直接発生した例外のみを処理できます。呼び出された関数で例外が発生した場合でも (間接的であっても)、それを処理することもできます。例::

>>> def this_fails():

... x = 1/0

...

>>> try:

... this_fails()

... 詳細として ZeroDivisionError を除く:

... print '実行時エラーの処理:'、detail

...

実行時エラーの処理: 整数の除算またはゼロによる剰余

.. _tut - raise:

例外の発生 例外のスロー

==============================

:keyword:`raise`ステートメントを使用すると、プログラマは指定された

例外を強制的に発生させることができます。例:

プログラマは、:keyword:`raise` ステートメントを使用して、指定された例外を強制的に発生させることができます。例::

>>> raise NameError('HiThere')

トレースバック (最新の呼び出し最後):

ファイル ""、行 1、?

NameError: HiThere

:keyword:`raise` の唯一の引数は、発生する例外を示します。

これは、例外インスタンスまたは例外クラス (:class:`Exception` から派生

するクラス) である必要があります。 throw 発生した例外は、:keyword:`raise` の一意のパラメータによって識別されます。例外インスタンスまたは例外クラス (:class:`Exception` から継承されたクラス) である必要があります。

例外が発生したかどうかを判断する必要があるが、それを処理するつもりはない場合は、より単純な形式の :keyword:`raise` ステートメントを使用して、例外を

再発生させることができます。例外がスローされたかどうかを知る必要があるが、それを処理したくない場合は、:keyword:`raise`

ステートメントを使用すると、例外を簡単に再スローできます。

>>> try:

... raise NameError('HiThere')

... 例外 NameError:

... print '例外が発生しました!'

... raise

...

例外が発生しました!

トレースバック (最後の呼び出し):

ファイル ""、行 2、?

NameError: HiThere

.. _tut-userExceptions:

ユーザー定義の例外 ユーザー定義の例外

======================================= =

プログラムは、新しい例外クラスを作成することで独自の例外に名前を付けることができます (Python クラスの詳細については、

:ref:`tut-classes` を参照してください)。例外は通常、:exc:`Exception` クラスから派生する必要があります。

例:

プログラム内で新しい例外タイプを作成することで、独自の例外に名前を付けることができます (Python クラスの内容については、:ref:`tut-classes` を参照してください)。例外クラスは通常、

:exc:`Exception` クラスから直接または間接的に派生する必要があります。例::

>>> class MyError(Exception):

... def __init__(self, value ): A ... Self.value = Value

... def __Str __ (Self):

... Return Repr (Self.value)

...

& gt;

:

:

:

:

:

:

:

:

:

:

:

:

:

... raise MyError(2*2) )

... MyError as e:

を除く ... print '例外が発生しました、値:', e.value

...

例外が発生しました、値 : 4

🎜 >>> ; MyError('おっと!') を発生させます🎜

トレースバック (最新の呼び出しは最後):

ファイル ""、1 行目、?

__main__.MyError: 'oops!'

この例では、デフォルトの :meth:`__init__` は次のとおりです。 class:`Exception` がオーバーライドされました

。新しい動作は単に *value* 属性を作成するだけであり、*args* 属性を作成するデフォルトの動作を置き換えます。

この例では、:class:`Exception`デフォルトの :meth:`__init__` はオーバーライドされます。

value プロパティを簡単に作成する新しい方法。これは、*args* 属性を作成する元の方法を置き換えます。

例外クラスは、他のクラスが実行できることをすべて定義できますが、

は通常は単純に保たれ、多くの場合、例外のハンドラーによって

エラーに関する情報を抽出できるようにする多数の属性のみを提供します。

複数の異なるエラーを発生させる可能性のあるモジュールを作成する場合、一般的な方法は、

そのモジュールで定義された例外の基本クラスを作成し、そのサブクラスを作成することです

さまざまなエラー条件に対応する特定の例外クラスを作成します。

例外クラスは次のように定義できます。他のクラスで定義できるものはすべて定義できますが、通常はシンプルにするために、例外処理ハンドラーが抽出できるようにいくつかの属性情報のみが追加されます。新しく作成したモジュールが複数の異なるエラーをスローする必要がある場合、一般的なアプローチは、モジュールの例外基本クラスを定義し、さまざまなエラー タイプに対応する例外サブクラスを派生することです。 ::

class Error(Exception):

"""このモジュールの例外の基本クラス。"""

pass

class InputError(Error):

"""入力のエラーに対して例外が発生しました。 ️属性: :

self.expr = expr

G Self.msg = msg

クラス遷移エラー (エラー):

「」は、操作が古くない状態遷移を試行するときに発生します。

遷移の始まり

次に -- 新しい状態を試みます

self.msg = msg

ほとんどの例外。標準例外の

の名前と同様に、「Error」で終わる名前で定義されています。 " 最後に。

多くの標準モジュールは、定義した関数で発生する可能性のあるエラーを報告するための独自の例外を定義しています

クラスの詳細については、

章:ref:`tut-classes` で説明されています。独自の例外を作成して、定義した関数で発生する可能性のあるエラーを報告します。クラスの詳細については、:ref:`tut-classes` の章を参照してください。

.. _tut-cleanup:

クリーンアップ アクションの定義 クリーンアップ アクションの定義

============================ ==== ======================

:keyword:`try` ステートメントには、クリーンアップを定義するための別のオプションの句があります

For

example:

:keyword:`try` ステートメントには別のオプションの句があり、その目的は、どのような状況でも実行する必要がある関数

を定義することです。例::

>>> try:

... KeyboardInterrupt

を発生させる ... 最後に:

... 「さようなら、世界!」を印刷します

...

さようなら、世界!

トレースバック (最新の呼び出しは最後):

ファイル ""、2 行目、?

KeyboardInterrupt

:keyword:`try` を離れる前に *finally 句* が常に実行されます

例外が発生したかどうかを示すステートメント。 :keyword:`try` 句で例外が発生し、

によって処理されなかった場合。

:keyword:`excel` 句 (または、:keyword:`Except` または

:keyword:`else` 句で発生した場合)、:keyword:`finally` 句の後に再生成されます

:keyword:`finally` 節は、:keyword:`try` ステートメントの他の節が

:keyword:`break`、:keyword を介して終了したときにも「途中で」実行されます

。 :` continue` または :keyword:`return` ステートメントのさらに複雑な例 (:keyword:`excel` と :keyword:`finally` 句がある

同じ :keyword:`try` ステートメントが機能します) Python 2.5):

例外が発生するかどうかに関係なく、プログラムが :keyword:`try` を終了した後に *finally 句* が常に実行されます。 :keyword:`Except` によってキャッチされない

例外が :keyword:`try` ステートメントで発生した場合 (または、それが :keyword:`Except` 句または :keyword:`else` 句で発生した場合)、

では:keyword:`finally` 句が実行された後に再スローされます。 :keyword:`try` ステートメントが :keyword:`break`、 :keyword:`Continue`、または :keyword:`return` によって終了した場合、 :keyword:`finally` 句も実行されます。これはより複雑な例です (同じ :keyword:`try` ステートメント内の :keyword:`excel` 節と :keyword:`finally` 節は Python 2.5 と同じように機能します)。 def Division(x, y):

... try:

... result = x / y

... ZeroDivisionError を除く:

... print "ゼロによる除算! "l ... Else :

... Print" 結果は ", Result

... 最後に:

... Print" 最後に句を実行しています "

...

& gt ;> 1)

結果は2です

finally句を実行しています

>>>divide(2, 0)

finally句を実行しています

>> 、"1")

finally句を実行しています

トレースバック(最新の呼び出しは最後):

ファイル ""、1行目、?

ファイル ""、3行目、分割中

TypeError: unsupported operand type(s) for /: 'str' and 'str'

ご覧のとおり、:keyword:`finally` 句はどのようなイベントでも実行されます。 2 つの文字列を分割することによって発生した文字列は、

:keyword:`excel` 句では処理されないため、:keyword:`finally`

句が実行された後に再発生します。

ご覧のとおり、次のとおりです。キーワード:`finally` 句はどのような場合でも実行されます。 :exc:`TypeError`

は 2 つの文字列が分割されたときにスローされ、:keyword:`excel` 節ではキャッチされないため、

:keyword:`finally` 節が実行された後に再スローされます。

実際のアプリケーションでは、:keyword:`finally` 句は、リソースの使用が成功したかどうかに関係なく

外部リソース (ファイルやネットワーク接続など) を解放する場合に便利です。アプリケーション アプリケーションでは、使用中にエラーが発生したかどうかに関係なく、外部リソース (ファイル

やネットワーク接続など) を解放するために、:keyword:`finally` 句が使用されます。

.. _tut-cleanup-with:

事前定義されたクリーンアップアクション

============================ === =========================

一部のオブジェクトでは、オブジェクト

が不要になったときに実行される標準のクリーンアップ アクションが定義されています。オブジェクト

を使用した操作が成功したか失敗したか。次の例を見てください。ファイル

を開いてその内容を画面に出力しようとしています。

一部のオブジェクトは、オブジェクトの操作が成功したかどうかに関係なく、オブジェクトが不要になったときに有効になります。次の例では、ファイルを開いてその内容を画面に出力しようとします。 ::

for line in open("myfile.txt"):

print line

このコードの問題は、コードの実行が終了した後、一定時間ファイルを開いたままにしてしまうことです。

単純なスクリプトでは問題になりませんが、

:keyword:`with` ステートメントを使用すると、ファイルなどのオブジェクトが常に迅速にクリーンアップされるように

することができます。 :

このコードの問題は、コードの実行後、開いているファイルがすぐに閉じられないことです。これは単純なスクリプト

では問題ありませんが、大規模なアプリケーションでは問題が発生する可能性があります。 :keyword:`with` ステートメントを使用すると、ファイルなどのオブジェクトをタイムリーかつ正確な方法でクリーンアップできます。 ::

with open("myfile.txt") as f:

for line in f:

print line

ステートメントの実行後、たとえ

問題が発生したとしても、ファイル *f* は常に閉じられます。

事前定義されたクリーンアップ アクションを提供する他のオブジェクトでは、

ステートメントの実行後、データの処理中にエラーが発生した場合でも、ファイル *f* は常に閉じられます。ファイル。

他のオブジェクトが事前定義されたクリーニング動作を提供する場合は、そのドキュメントを確認してください。

上記は Python 2.7 の基本的なチュートリアルです: エラーと例外 その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。


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