Python例外処理をマスター:包括的ガイド
概要
Pythonは、プログラム内の予期しないエラーを処理し、デバッグ機能を追加するための2つの重要な機能を提供します。
- 例外処理 - このチュートリアルで説明。Pythonで利用可能な標準例外の一覧: 標準例外
- アサーション - 「Pythonのアサーション」チュートリアルで説明
標準例外の一覧
| No. | 例外名と説明 |
|---|---|
| 1 | Exception - すべての例外の基底クラス |
| 2 | StopIteration - イテレータのnext()メソッドがオブジェクトを指さないときに発生 |
| 3 | SystemExit - sys.exit()関数によって発生 |
| 4 | StandardError - StopIterationとSystemExitを除くすべての組み込み例外の基底クラス |
| 5 | ArithmeticError - 数値計算で発生するすべてのエラーの基底クラス |
| 6 | OverflowError - 計算が数値型の最大限界を超えたときに発生 |
| 7 | FloatingPointError - 浮動小数点計算が失敗したときに発生 |
| 8 | ZeroDivisionError - すべての数値型でゼロ除算またはゼロ剰余が発生したときに発生 |
| 9 | AssertionError - assert文の失敗時に発生 |
| 10 | AttributeError - 属性参照または代入の失敗時に発生 |
| 11 | EOFError - raw_input()またはinput()関数からの入力がなく、ファイル末尾に達したときに発生 |
| 12 | ImportError - import文が失敗したときに発生 |
| 13 | KeyboardInterrupt - ユーザーがプログラム実行を中断したとき(通常Ctrl+C)に発生 |
| 14 | LookupError - すべての検索エラーの基底クラス |
| 15 | IndexError - インデックスがシーケンスに見つからないときに発生 |
| 16 | KeyError - 指定されたキーが辞書に見つからないときに発生 |
| 17 | NameError - 識別子がローカルまたはグローバル名前空間に見つからないときに発生 |
| 18 | UnboundLocalError - 関数やメソッドでローカル変数にアクセスしようとしたが、値が代入されていないときに発生 |
| 19 | EnvironmentError - Python環境外で発生するすべての例外の基底クラス |
| 20 | IOError - 入出力操作が失敗したとき(print文や、存在しないファイルを開こうとしたopen()関数など)に発生 |
| 21 | IOError - OS関連のエラーで発生 |
| 22 | SyntaxError - Pythonの構文エラー時に発生 |
| 23 | IndentationError - インデントが適切に指定されていないときに発生 |
| 24 | SystemError - インタープリタが内部問題を検出したときに発生するが、インタープリタは終了しない |
| 25 | SystemExit - sys.exit()関数でPythonインタープリタが終了するときに発生。コードで処理されない場合、インタープリタを終了させる |
| 26 | TypeError - 指定されたデータ型に対して無効な操作や関数が試みられたときに発生 |
| 27 | ValueError - 組み込み関数の引数の型は正しいが、値が無効なときに発生 |
| 28 | RuntimeError - どのカテゴリにも分類されない生成エラーが発生したときに発生 |
| 29 | NotImplementedError - 継承クラスで実装が必要な抽象メソッドが実際に実装されていないときに発生 |
Pythonのアサーション
アサーションは、プログラムのテストが完了したらオン/オフできる正常性チェックです。
アサーションを理解する最も簡単な方法は、raise-if文(より正確にはraise-if-not文)に例えることです。式を評価し、結果が偽の場合に例外を発生させます。
アサーションは、バージョン1.5で導入された最新のキーワードであるassert文によって実行されます。
プログラマはしばしば、関数の開始時に有効な入力をチェックするために、また関数呼び出し後に有効な出力をチェックするためにアサーションを配置します。
assert文
assert文に遭遇すると、Pythonは付随する式を評価します(望ましくは真である)。式が偽の場合、PythonはAssertionError例外を発生させます。
構文:
assert Expression[, Arguments]
アサーションが失敗した場合、PythonはArgumentExpressionをAssertionErrorの引数として使用します。AssertionError例外は、try-except文を使用して他の例外と同様に捕捉・処理できますが、処理されない場合はプログラムを終了させ、トレースバックを出力します。
例
ケルビン温度を華氏温度に変換する関数です。絶対零度(0ケルビン)より低い温度はあり得ないため、負の温度が指定された場合はエラーを出します。
#!/usr/bin/python
def KelvinToFahrenheit(Temperature):
assert (Temperature >= 0), "Colder than absolute zero!"
return ((Temperature - 273) * 1.8) + 32
print(KelvinToFahrenheit(273))
print(int(KelvinToFahrenheit(505.78)))
print(KelvinToFahrenheit(-5))
実行結果:
32.0
451
Traceback (most recent call last):
File "test.py", line 9, in
print(KelvinToFahrenheit(-5))
File "test.py", line 4, in KelvinToFahrenheit
assert (Temperature >= 0), "Colder than absolute zero!"
AssertionError: Colder than absolute zero!
例外とは
例外とは、プログラム実行中に発生し、プログラムの命令の正常な流れを中断するイベントです。一般的に、Pythonスクリプトが対処できない状況に遭遇すると、例外を発生させます。例外はエラーを表すPythonオブジェクトです。
Pythonスクリプトが例外を発生させた場合、即座に処理するか、そうでなければプログラムは終了します。
例外の処理
例外を発生させる可能性のあるsuspicious(疑わしい)コードがある場合、そのコードをtry:ブロックに配置することでプログラムを防御できます。try:ブロックの後にexcept:文を記述し、その後に問題をできるだけ優雅に処理するコードブロックを続けます。
構文
try....except...elseブロックの簡単な構文:
try:
ここに操作を記述
......................
except ExceptionI:
ExceptionIが発生した場合、このブロックを実行
except ExceptionII:
ExceptionIIが発生した場合、このブロックを実行
......................
else:
例外が発生しなかった場合、このブロックを実行
上記構文の重要なポイント:
- 単一のtry文に複数のexcept文を持たせられる。tryブロックに異なるタイプの例外をスローする文が含まれる場合に有用
- 汎用的なexcept節を指定して、あらゆる例外を処理することも可能
- except節の後にelse節を含められる。try:ブロックのコードが例外を発生させなかった場合、elseブロックのコードが実行される
- elseブロックは、try:ブロックの保護を必要としないコードを置くのに適している
例:正常なケース
#!/usr/bin/python
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
except IOError:
print("Error: can't find file or read data")
else:
print("Written content in the file successfully")
fh.close()
実行結果:
Written content in the file successfully
例:例外が発生するケース
#!/usr/bin/python
try:
fh = open("testfile", "r")
fh.write("This is my test file for exception handling!!")
except IOError:
print("Error: can't find file or read data")
else:
print("Written content in the file successfully")
実行結果:
Error: can't find file or read data
例外を指定しないexcept節
例外を指定せずにexcept文を使用することもできます。
try:
ここに操作を記述
......................
except:
何らかの例外が発生した場合、このブロックを実行
......................
else:
例外が発生しなかった場合、このブロックを実行
この種類のtry-except文は、発生するすべての例外を捕捉します。ただし、問題の根本原因を特定しないため、良いプログラミング習慣とは見なされません。
複数の例外を処理するexcept節
同じexcept文で複数の例外を処理することもできます。
try:
ここに操作を記述
......................
except(Exception1[, Exception2[,...ExceptionN]]]):
与えられた例外リストのいずれかが発生した場合、このブロックを実行
......................
else:
例外が発生しなかった場合、このブロックを実行
try-finally節
finally:ブロックをtry:ブロックと共に使用できます。finallyブロックは、tryブロックが例外を発生させたかどうかに関わらず、必ず実行されるコードを配置する場所です。try-finally文の構文:
try:
ここに操作を記述
......................
例外によりスキップされる可能性あり
finally:
これは常に実行される
......................
else節とfinally節を同時に使用することはできません。
例
#!/usr/bin/python
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
finally:
print("Error: can't find file or read data")
書き込みモードでファイルを開く権限がない場合、以下の結果になります。
Error: can't find file or read data
よりクリーンに書く例:
#!/usr/bin/python
try:
fh = open("testfile", "w")
try:
fh.write("This is my test file for exception handling!!")
finally:
print("Going to close the file")
fh.close()
except IOError:
print("Error: can't find file or read data")
tryブロックで例外がスローされると、実行は即座にfinallyブロックに移ります。finallyブロックのすべての文が実行された後、例外が再度発生し、より上位のtry-except文のexcept文で処理されます(存在する場合)。
例外の引数
例外には引数を持たせることができ、問題に関する追加情報を提供します。引数の内容は例外によって異なります。except節で変数を指定することで、例外の引数を取得できます。
try:
ここに操作を記述
......................
except ExceptionType, Argument:
ここでArgumentの値を出力...
単一の例外を処理するコードを書く場合、except文で例外名の後に変数を続けることができます。複数の例外を捕捉する場合、例外のタプルの後に変数を続けられます。
この変数には、主に例外の原因を含む値が入ります。単一の値や、タプルの形で複数の値を受け取れます。このタプルには通常、エラー文字列、エラー番号、エラー位置が含まれます。
例:単一の例外
#!/usr/bin/python
# 関数を定義
def temp_convert(var):
try:
return int(var)
except ValueError, Argument:
print("The argument does not contain numbers\n", Argument)
# 上記関数を呼び出し
temp_convert("xyz")
実行結果:
The argument does not contain numbers
invalid literal for int() with base 10: 'xyz'
例外の発生
raise文を使用して、いくつかの方法で例外を発生させられます。raise文の一般的な構文:
raise [Exception [, args [, traceback]]]
Exceptionは例外のタイプ(例:NameError)、argumentは例外引数の値です。引数は省略可能で、指定しない場合はNoneになります。最後の引数tracebackも省略可能(実際には滅多に使用されない)で、存在する場合は例外に使用されるトレースバックオブジェクトです。
例
例外は文字列、クラス、オブジェクトのいずれかです。Pythonコアが発生させるほとんどの例外はクラスで、引数はそのクラスのインスタンスです。新しい例外の定義は簡単です。
def functionName(level):
if level < 1:
raise "Invalid level!", level
# このコードは例外が発生すると実行されません
注意: 例外を捕捉するには、"except"節がスローされた同じ例外(クラスオブジェクトまたは単純な文字列)を参照する必要があります。上記の例外を捕捉するには、except節を以下のように記述します。
try:
ビジネスロジック...
except "Invalid level!":
例外処理...
else:
残りのコード...
ユーザー定義例外
Pythonでは、標準の組み込み例外から派生したクラスを作成することで、独自の例外を定義できます。
以下は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)
Python
- Python データ型マスター: 実践ガイド
- Python 演算子完全マスター: 包括的ガイド
- Python pass文完全マスター: 実践ガイド
- Python 関数引数完全マスター: 位置引数・キーワード引数・デフォルト引数
- Python辞書完全ガイド:作成、操作、高度なテクニック
- Pythonエラーと組み込み例外をマスターする
- Python例外処理マスター:try、except、else、finallyを徹底解説
- Pythonカスタム例外マスター:実践ガイド
- Pythonイテレータ完全ガイド:仕組みと自作方法
- Pythonクロージャ解説:ネスト関数が変数を捕捉する仕組み
- Python datetimeマスター:日付・時刻・タイムゾーン実践ガイド