第18回.例外処理(try文)とexception一覧
スクリプトを実行したときには各種の例外(エラー)が発生することがあります。
スクリプトを書いて実行し、エラーが出れば修正してまた実行する。
これを繰り返すことでエラーのないプログラムが完成していきます。
それは、プログラムの動作環境(データや外部環境)がその時々で変わるため、これらを完全には考慮しきれないからです。
しかし大抵の場合は強制終了されては困るものです。
Pythonには例外発生時に強制終了させずに例外を検知する手段としてtry文が用意されています。
目次
例外処理とは
def substr3(s):
"""文字列の3文字目を返す
:param s: 入力文字列
:return: sの3文字め
"""
return s[2]
lang = ("Python","VBA","GAS","C","C##")
for s in lang:
print(substr3(s))
例外(エラー)発生時の画面
デバッグについて
上記を見ると、
↓
return s[2]
print(substr3(s))これで呼ばれた関数substr3の中で、
return s[2]ここでインデックスが範囲外になったことが分かります。
引数の文字列を確認して、適切な対処する必要があります。
そのような場合でもスクリプトが強制終了されることなく処理を続けるためにtry文がPythonには用意されています。
※もちろん上記の場合は文字列長を判定して何らかの対処をしたほうが良いです。
try文の文法
try文の構文
try:
例外が発生するかもしれない処理
except 捕捉する例外ハンドラ as 識別子:
発生した例外に対する処理
else:
例外が発生しなかった場合の処理
finally:
例外発生の有無に関わらず実行する処理
except節
複数のexcept節を記述できます。
例外が発生すると、except節を上から逐次、発生した例外に対応するまで調べます。
いずれのexcept節にも合致しなかった場合は、例外発生によって実行は強制終了されます。
識別子(変数)に例外オブジェクトが格納されます。
この識別子(変数)はexcep節の最後にクリアされるで、他で使用することはできません。
else節
例外(エラー)が発生しなかった場合のみ実行されます。
else節で起きた例外は、手前にあるexcept節では処理されません。
finally節
後始末の処理です。
エラーの有無に関わらず実行されます。
finally節で起きた例外は、手前にあるexcept節では処理されません。
以下の使用例を通して、
例外ハンドラの指定やtry文のネストについての挙動を理解してください。
try文の使用例
def substr3(s):
"""文字列の3文字目を返す
:param s: 入力文字列
:return: sの3文字め
"""
return s[2]
lang = ("Python","VBA","GAS","C","C##")
for s in lang:
print(substr3(s))
IndexError: string index out of range
このエラーになります。
try文を入れてスクリプトが停止しないようにします。
例外ハンドラを省略したexcept
try:
lang = ("Python","VBA","GAS","C","C##")
for s in lang:
print(substr3(s))
except:
print("エラー発生")
上記を実行すると、
エラーになった場合でもforループを継続したい場合は、forの中にtry文を入れます。
lang = ("Python","VBA","GAS","C","C##")
for s in lang:
try:
print(substr3(s))
except:
print("エラー発生")
例外ハンドラを指定したexcept
lang = ("Python","VBA","GAS","C","C##")
for s in lang:
try:
print(substr3(s))
except IndexError as e:
print(f"{s}:{e}")
lang = ("Python","VBA",1234,"C","C##")
for s in lang:
try:
print(substr3(s))
except IndexError as e:
print(f"{s}:{e}")
複数の例外ハンドラの指定
lang = ("Python","VBA",1234,"C","C##")
for s in lang:
try:
print(substr3(s))
except IndexError as e:
print(f"{s}:{e}")
except TypeError as e:
print(f"{s}:{e}")
上記の2つのexcept節は中の処理が同じなので、1行にすることができます。
lang = ("Python","VBA",1234,"C","C##")
for s in lang:
try:
print(substr3(s))
except (IndexError, TypeError) as e:
print(f"{s}:{e}")
これでIndexErrorとTypeErrorの例外に対応できていますが、その他の例外が発生した場合はスクリプトが強制終了します。
想定外の例外でも終了しないようにするなら、以下のように例外ハンドラを指定しないexcept節を最後に付けておきます。
lang = ("Python","VBA",1234,"C","C##")
for s in lang:
try:
1/0
print(substr3(s))
except (IndexError, TypeError) as e:
print(f"{s}:{e}")
except:
print("想定外のエラー")
try文のネスト
lang = ("Python","VBA","C",1234,"C##")
try:
for s in lang:
try:
print(substr3(s))
except IndexError as e:
print(f"{s}:{e}")
except TypeError as e:
print(f"{s}:{e}")
IndexError以外の例外が発生した場合は、for文の中のtryでは例外を補足できません。
この場合の例外発生時には、さらに上のレベル(外側)にtryがあるか探索されます。
tryがあり、合致するexcept節があればそこで補足されます。
関数の中と呼び出し元の両方でtry文を使う
def substr3(s):
"""文字列の3文字目を返す
:param s: 入力文字列
:return: sの3文字め
"""
try:
return s[2]
except IndexError:
return ""
lang = ("Python","VBA","C",1234,"C##")
for s in lang:
try:
print(substr3(s))
except TypeError as e:
print(f"{s}:{e}")
IndexError以外の例外が発生した場合は、関数の中のtryでは例外を補足できません。
この場合、例外発生時には、関数の呼び出し元にtryがあるか探索されます。
tryがあり、合致するexcept節があればそこで補足されます。
else節とfinally節
def substr3(s):
"""文字列の3文字目を返す
:param s: 入力文字列
:return: sの3文字め
"""
return s[2]
try:
lang = ("Python","VBA","GAS","C","C##")
for s in lang:
print(substr3(s))
except:
print("エラー発生")
else:
print("全て正常")
finally:
print("完了しました。")
入力するデータを以下に変更してみます。
lang = ("Python","VBA","GAS","PHP","C##")
そして、finally節は常に処理されていることが確認できます。
組み込み例外一覧
Base | 全ての組み込み例外の基底クラスです。 ユーザ定義の例外に直接継承されることは意図されていません (継承にはExceptionを使ってください)。 |
exception | システム終了以外の全ての組み込み例外はこのクラスから派生しています。 全てのユーザ定義例外もこのクラスから派生させるべきです。 |
ArithmeticError | 算術上の様々なエラーに対して送出される組み込み例外 |
BufferError | バッファに関連する操作が行えなかったときに送出されます。 |
LookupError | マッピングまたはシーケンスで使われたキーやインデクスが無効な場合に送出される例外IndexErrorおよびKeyErrorの基底クラスです。 |
具象例外
AssertionError | assert文が失敗した場合に送出されます。 |
AttributeError | 属性参照 (属性参照を参照) や代入が失敗した場合に送出されます (オブジェクトが属性の参照や属性の代入をまったくサポートしていない場合にはTypeErrorが送出されます)。 |
EOFError | input()が何もデータを読まずに end-of-file (EOF) に達した場合に送出されます。 |
FloatingPointError | 現在は使われていません。 |
GeneratorExit | ジェネレータやコルーチンが閉じられたときに送出されます。 この例外はエラーではなく技術的なものなので、ExceptionではなくBaseExceptionを直接継承しています。 |
ImportError | import文でモジュールをロードしようとして問題が発生すると送出されます。 from...importの中の"from list" (訳注:...の部分)の名前が見つからないときにも送出されます。 |
ModuleNotFoundError | ImportErrorのサブクラスで、import文でモジュールが見つからない場合に送出されます。 また、sys.modulesにNoneが含まれる場合にも送出されます。 |
IndexError | シーケンスの添字が範囲外の場合に送出されます。 (スライスのインデクスはシーケンスの範囲に収まるように暗黙のうちに調整されます。 インデクスが整数でない場合、TypeErrorが送出されます。) |
KeyError | マッピング (辞書) のキーが、既存のキーの集合内に見つからなかった場合に送出されます。 |
KeyboardInterrupt | ユーザが割り込みキー (通常はControl-CまたはDelete) を押した場合に送出されます。実行中、割り込みは定期的に監視されます。 Exceptionを捕捉するコードに誤って捕捉されてインタプリタの終了が阻害されないように、この例外はBaseExceptionを継承しています。 |
MemoryError | ある操作中にメモリが不足したが、その状況は (オブジェクトをいくつか消去することで) まだ復旧可能かもしれない場合に送出されます。 |
NameError | ローカルまたはグローバルの名前が見つからなかった場合に送出されます。 これは非修飾の (訳注:spam.eggではなく単にeggのような) 名前のみに適用されます。 関連値は見つからなかった名前を含むエラーメッセージです。 |
NotImplementedError | この例外はRuntimeErrorから派生しています。 ユーザ定義の基底クラスにおいて、抽象メソッドが派生クラスでオーバライドされることを要求する場合にこの例外を送出しなくてはなりません。 またはクラスは実装中であり本来の実装を追加する必要があることを示します。 |
OSError([arg]) | この例外はシステム関数がシステム関連のエラーを返した場合に送出されます。 |
OverflowError | 算術演算の結果が表現できない大きな値になった場合に送出されます。 これは整数では起こりません (むしろMemoryErrorが送出されることになるでしょう)。 しかし、歴史的な理由のため、要求された範囲の外の整数に対して OverflowError が送出されることがあります。 C の浮動小数点演算の例外処理は標準化されていないので、ほとんどの浮動小数点演算もチェックされません。 |
RecursionError | この例外はRuntimeErrorを継承しています。 インタープリタが最大再帰深度 (sys.getrecursionlimit()を参照) の超過を検出すると送出されます。 |
ReferenceError | weakref.proxy()によって生成された弱参照 (weak reference) プロキシを使って、ガーベジコレクションによって回収された後の参照対象オブジェクトの属性にアクセスした場合に送出されます。 弱参照についてはweakrefモジュールを参照してください。 |
RuntimeError | 他のカテゴリに分類できないエラーが検出された場合に送出されます。 関連値は、何が問題だったのかをより詳細に示す文字列です。 |
StopIteration | 組込み関数next()とiteratorの__next__()メソッドによって、そのイテレータが生成するアイテムがこれ以上ないことを伝えるために送出されます。 |
StopAsyncIteration | イテレーションを停止するために、asynchronous iteratorオブジェクトの__anext__()メソッドによって返される必要があります。 |
SyntaxError | パーザが構文エラーに遭遇した場合に送出されます。 この例外はimport文、組み込み関数exec()やeval()、初期化スクリプトの読み込みや標準入力で (対話的な実行時にも) 起こる可能性があります。 |
IndentationError | 正しくないインデントに関する構文エラーの基底クラスです。 これはSyntaxErrorのサブクラスです。 |
TabError | タブとスペースを一貫しない方法でインデントに使っているときに送出されます。 これはIndentationErrorのサブクラスです。 |
SystemError | インタプリタが内部エラーを発見したが、状況は全ての望みを棄てさせるほど深刻ではないと思われる場合に送出されます。 関連値は (下位層で) どの動作が失敗したかを示す文字列です。 |
SystemExit | この例外はsys.exit()関数から送出されます。 Exceptionをキャッチするコードに誤ってキャッチされないように、ExceptionではなくBaseExceptionを継承しています。 これにより例外は上の階層に適切に伝わり、インタープリタを終了させます。 この例外が処理されなかった場合はスタックのトレースバックを表示せずに Python インタープリタは終了します。 |
TypeError | 組み込み演算または関数が適切でない型のオブジェクトに対して適用された際に送出されます。 関連値は型の不整合に関して詳細を述べた文字列です。 |
UnboundLocalError | 関数やメソッド内のローカルな変数に対して参照を行ったが、その変数には値が代入されていなかった場合に送出されます。 |
UnicodeError | Unicode に関するエンコードまたはデコードのエラーが発生した際に送出されます。 |
UnicodeEncodeError | Unicode 関連のエラーがエンコード中に発生した際に送出されます。 |
UnicodeDecodeError | Unicode 関連のエラーがデコード中に発生した際に送出されます。 |
UnicodeTranslateError | Unicode 関連のエラーが変換中に発生した際に送出されます。 |
ValueError | 演算子や関数が、正しい型だが適切でない値を持つ引数を受け取ったときや、IndexErrorのようなより詳細な例外では記述できない状況で送出されます。 |
ZeroDivisionError | 除算や剰余演算の第二引数が 0 であった場合に送出されます。 関連値は文字列で、その演算における被演算子と演算子の型を示します。 |
BlockingIOError | ある操作が、ノンブロッキング操作に設定されたオブジェクト (例えばソケット) をブロックしそうになった場合に送出されます。 |
ChildProcessError | 子プロセスの操作が失敗した場合に送出されます。 |
ConnectionError | コネクション関係の問題の基底クラス。 |
BrokenPipeError | ConnectionErrorのサブクラスで、もう一方の端が閉じられたパイプに書き込こもうとするか、書き込みのためにシャットダウンされたソケットに書き込こもうとした場合に発生します。 |
ConnectionAbortedError | ConnectionErrorのサブクラスで、接続の試行が通信相手によって中断された場合に発生します。 |
ConnectionRefusedError | ConnectionErrorのサブクラスで、接続の試行が通信相手によって拒否された場合に発生します。 |
ConnectionResetError | ConnectionErrorのサブクラスで、接続が通信相手によってリセットされた場合に発生します。 |
FileExistsError | すでに存在するファイルやディレクトリを作成しようとした場合に送出されます。 |
FileNotFoundError | 要求されたファイルやディレクトリが存在しない場合に送出されます。 |
InterruptedError | システムコールが入力信号によって中断された場合に送出されます。 |
IsADirectoryError | ディレクトリに (os.remove()などの) ファイル操作が要求された場合に送出されます。 |
NotADirectoryError | ディレクトリ以外のものに (os.listdir()などの) ディレクトリ操作が要求された場合に送出されます。 |
PermissionError | 十分なアクセス権、例えばファイルシステム権限のない操作が試みられた場合に送出されます。 |
ProcessLookupError | 与えられたプロセスが存在しない場合に送出されます。 |
TimeoutError | システム関数がシステムレベルでタイムアウトした場合に送出されます。 |
同じテーマ「Python入門」の記事
第15回.lambda(ラムダ式、無名関数)と三項演算子
第16回.Pythonの引数は参照渡しだが・・・
第17回.リスト内包表記
第18回.例外処理(try文)とexception一覧
第19回.import文(パッケージ・モジュールのインポート)
第20回.フォルダとファイルの一覧を取得(os,glob,pathlib)
第21回.CSV読み込みとopen()関数とwith文
第22回.CSV読み書き(csvモジュール)
第23回.pipコマンド(外部ライブラリのインストール)
第24回.エクセルを操作する(openpyxl)
第24回.エクセルを操作する(pywin32:win32com)
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.条件分岐(Select Case)|VBA入門
9.メッセージボックス(MsgBox関数)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。