Python 例外処理

Python は、Python プログラムの実行中に発生する例外とエラーを処理するための、非常に重要な2つの機能を提供します。この機能を使用して Python プログラムをデバッグできます。

  • 例外処理: 当サイトのPythonチュートリアルで具体的に紹介します。
  • アサーション: 当サイトのPythonチュートリアルで具体的に紹介します。

Python 標準例外

例外名説明
BaseExceptionすべての例外の基底クラス
SystemExitインタープリタが終了を要求
KeyboardInterruptユーザーによる実行の中断(通常は ^C 入力)
Exception通常のエラーの基底クラス
StopIteration イテレータにそれ以上の値がない
GeneratorExit ジェネレータが終了を通知するために例外を発生させる
StandardErrorすべての組み込み標準例外の基底クラス
ArithmeticError すべての数値計算エラーの基底クラス
FloatingPointError 浮動小数点計算エラー
OverflowError数値演算が最大制限を超えた
ZeroDivisionErrorゼロ除算(またはゼロ剰余)(すべてのデータ型)
AssertionErrorアサーション文が失敗
AttributeErrorオブジェクトにこの属性がない
EOFError 組み込み入力がなく、EOFマーカーに到達
EnvironmentError オペレーティングシステムエラーの基底クラス
IOError 入出力操作の失敗
OSError オペレーティングシステムエラー
WindowsErrorシステムコールの失敗
ImportError モジュール/オブジェクトのインポート失敗
LookupError 無効なデータクエリの基底クラス
IndexErrorシーケンスにこのインデックスがない
KeyErrorマッピングにこのキーがない
MemoryErrorメモリオーバーフローエラー(Python インタープリタにとって致命的ではない)
NameError未宣言/未初期化のオブジェクト(属性がない)
UnboundLocalError 未初期化のローカル変数にアクセス
ReferenceError弱参照がガベージコレクション済みのオブジェクトにアクセスしようとした
RuntimeError 一般的なランタイムエラー
NotImplementedError未実装のメソッド
SyntaxErrorPython 構文エラー
IndentationErrorインデントエラー
TabErrorTab とスペースの混用
SystemError 一般的なインタープリタシステムエラー
TypeError型に対して無効な操作
ValueError 無効な引数が渡された
UnicodeError Unicode 関連のエラー
UnicodeDecodeError Unicode デコード時のエラー
UnicodeEncodeError Unicode エンコード時のエラー
UnicodeTranslateErrorUnicode 変換時のエラー
Warning 警告の基底クラス
DeprecationWarning非推奨の機能に関する警告
FutureWarning 将来のセマンティクスが変更される構造に関する警告
OverflowWarning自動的に long 整数に昇格することに関する古い警告
PendingDeprecationWarning機能が非推奨になることに関する警告
RuntimeWarning 疑わしいランタイム動作に関する警告
SyntaxWarning疑わしい構文に関する警告
UserWarningユーザーコードによって生成された警告

例外とは?

例外とは、プログラムの実行中に発生し、プログラムの正常な実行に影響を与えるイベントです。

一般に、Python がプログラムを正常に処理できない場合に例外が発生します。

例外は Python オブジェクトであり、エラーを表します。

Python スクリプトで例外が発生した場合、それを捕捉して処理する必要があります。そうしないとプログラムの実行が終了します。


例外処理

例外を捕捉するには try/except 文を使用できます。

try/except 文は try ブロック内のエラーを検出し、except 文が例外情報を捕捉して処理できるようにします。

例外が発生したときにプログラムを終了させたくない場合は、try 内で捕捉するだけです。

構文:

以下は簡単な...try....except...elseの構文:

try:
<语句>        #运行别的代码
except <名字>:
<语句>        #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句>        #如果引发了'name'异常,获得附加的数据
else:
<语句>        #如果没有异常发生

try の仕組みは、try 文を開始すると、Python は現在のプログラムのコンテキストにマークを付け、例外が発生したときにここに戻れるようにします。try 句が最初に実行され、次に何が起こるかは、実行時に例外が発生したかどうかに依存します。

  • try の後のステートメントの実行中に例外が発生した場合、Python は try に戻り、その例外に一致する最初の except 句を実行します。例外の処理が完了すると、制御フローは try 文全体を通過します(例外の処理中に新しい例外が発生しない限り)。
  • try の後のステートメントで例外が発生したが、一致する except 句がない場合、例外は上位の try に渡されるか、プログラムの最上位に渡されます(これによりプログラムは終了し、デフォルトのエラーメッセージが表示されます)。
  • try 句の実行中に例外が発生しなかった場合、Python は else 文の後のステートメント(else がある場合)を実行し、制御フローは try 文全体を通過します。

例

以下は簡単な例です。ファイルを開いて、そのファイルに内容を書き込みますが、例外は発生しません:

例

#!/usr/bin/python
# -*- coding: UTF-8 -*-

try:
    fh = open("testfile", "w")
    fh.write("これはテストファイルです。例外をテストするためのものです!!")
except IOError:
    print "エラー: ファイルが見つからないか、ファイルの読み取りに失敗しました"
else:
    print "ファイルへの内容の書き込みに成功しました"
    fh.close()

上記プログラムの出力結果:

$ python test.py 
内容写入文件成功
$ cat testfile       # 查看写入的内容
这是一个测试文件,用于测试异常!!

例

以下は簡単な例です。ファイルを開いて、そのファイルに内容を書き込もうとしますが、ファイルに書き込み権限がないため、例外が発生します:

例

#!/usr/bin/python
# -*- coding: UTF-8 -*-

try:
    fh = open("testfile", "w")
    fh.write("これはテストファイルです。例外をテストするためのものです!!")
except IOError:
    print "エラー: ファイルが見つからないか、ファイルの読み取りに失敗しました"
else:
    print "ファイルへの内容の書き込みに成功しました"
    fh.close()

コードを実行する前に、テストを簡単にするために、testfile ファイルの書き込み権限を削除しておきます。コマンドは次のとおりです:

chmod -w testfile

もう一度上記のコードを実行します:

$ python test.py 
Error: 没有找到文件或读取文件失败

except を例外タイプなしで使用する

例外タイプを指定せずに except を使用できます。次の例のとおりです:

try:
    正常的操作
   ......................
except:
    发生异常,执行这块代码
   ......................
else:
    如果没有异常执行这块代码

上記の方法では、try-except 文は発生したすべての例外を捕捉します。しかし、これは良い方法ではありません。このプログラムでは具体的な例外情報を識別できないからです。単にすべての例外を捕捉しているだけです。


except を複数の例外タイプとともに使用する

同じ except 文を使用して複数の例外情報を処理することもできます。次のようにします:

try:
    正常的操作
   ......................
except(Exception1[, Exception2[,...ExceptionN]]):
   发生以上多个异常中的一个,执行这块代码
   ......................
else:
    如果没有异常执行这块代码

try-finally 文

try-finally 文は、例外が発生するかどうかに関係なく、最後のコードを実行します。

try:
<语句>
finally:
<语句>    #退出try时总会执行
raise

例

例

#!/usr/bin/python
# -*- coding: UTF-8 -*-

try:
    fh = open("testfile", "w")
    fh.write("これはテストファイルです。例外をテストするためのものです!!")
finally:
    print "エラー: ファイルが見つからないか、ファイルの読み取りに失敗しました"

開いたファイルに書き込み権限がない場合、出力は次のようになります:

$ python test.py 
Error: 没有找到文件或读取文件失败

同じ例は次のように書くこともできます:

例

#!/usr/bin/python
# -*- coding: UTF-8 -*-

try:
    fh = open("testfile", "w")
    try:
        fh.write("これはテストファイルです。例外をテストするためのものです!!")
    finally:
        print "ファイルを閉じる"
        fh.close()
except IOError:
    print "エラー: ファイルが見つからないか、ファイルの読み取りに失敗しました"

try ブロック内で例外がスローされると、すぐに finally ブロックのコードが実行されます。

finally ブロック内のすべてのステートメントが実行された後、例外が再度スローされ、except ブロックのコードが実行されます。

引数の内容は例外とは異なります。


例外の引数

例外には引数を付けることができ、出力される例外情報の引数として使用できます。

except 文を使用して例外の引数を捕捉できます。次のようにします:

try:
    正常的操作
   ......................
except ExceptionType, Argument:
    你可以在这输出 Argument 的值...

変数が受け取る例外値は、通常、例外のステートメントに含まれています。タプルの形式で、変数は1つまたは複数の値を受け取ることができます。

タプルには通常、エラー文字列、エラー番号、エラー位置が含まれます。

例

以下は単一の例外の例です:

例

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 関数を定義
def temp_convert(var):
    try:
        return int(var)
    except ValueError, Argument:
        print "引数に数字が含まれていません\n", Argument

# 関数を呼び出し
temp_convert("xyz")

上記プログラムの実行結果は次のとおりです:

$ python test.py 
参数没有包含数字
invalid literal for int() with base 10: 'xyz'

例外を発生させる

raise 文を使用して自分で例外を発生させることができます

raise の構文形式は次のとおりです:

raise [Exception [, args [, traceback]]]

文の中で Exception は例外のタイプ(例: NameError)で、標準例外の中の任意の1つです。args は自分で提供する例外の引数です。

最後のパラメータはオプションです(実際にはほとんど使用されません)。存在する場合、追跡例外オブジェクトです。

例

例外は、文字列、クラス、またはオブジェクトのいずれかです。Pythonのコアが提供する例外のほとんどはインスタンス化されたクラスであり、これはクラスのインスタンスのパラメータです。

例外の定義は非常に簡単で、次のようになります:

例

def functionName( level ):
    if level < 1:
        raise Exception("Invalid level!", level)
        # 例外を発生させると、後続のコードは実行されません

注意:例外をキャッチするには、"except"文が同じ例外を使用してクラスオブジェクトまたは文字列をスローする必要があります。

たとえば、上記の例外をキャッチする場合、"except"文は次のようになります:

try:
    正常逻辑
except Exception,err:
    触发自定义异常    
else:
    其余代码

例

例

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 関数を定義
def mye( level ):
    if level < 1:
        raise Exception,"Invalid level!"
        # 例外を発生させると、後続のコードは実行されません
try:
    mye(0)            # 例外を発生させる
except Exception,err:
    print 1,err
else:
    print 2

上記のコードを実行すると、出力結果は次のようになります:

$ python test.py 
1 Invalid level!

ユーザー定義例外

新しい例外クラスを作成することで、プログラムは独自の例外に名前を付けることができます。例外は通常、直接的または間接的にExceptionクラスを継承する必要があります。

以下はRuntimeErrorに関連する例です。この例では、RuntimeErrorを基底クラスとするクラスを作成し、例外発生時により多くの情報を出力します。

try文ブロック内でユーザー定義の例外が発生すると、exceptブロック文が実行されます。変数 e はNetworkerrorクラスのインスタンスを作成するために使用されます。

class Networkerror(RuntimeError):
    def __init__(self, arg):
        self.args = arg

上記のクラスを定義した後、次のように例外を発生させることができます:

try:
    raise Networkerror("Bad hostname")
except Networkerror,e:
    print e.args
その他の拡張