Pythonの例外とその処理に関する覚え書き(ユーザ定義の例外など)
「Pythonの例外とその処理に関する覚え書き(概要、書式、後始末処理)」に続いて、例外に関して幾つかのことをまとめておく。
(2014/11/13)リンク先を修正し、サンプルコードの内容もPython 3に対応し、本文の記述も一部書き直している。
else節
例外が発生した場合の処理はexcept節に記述するが、発生しなかったときにだけ行いたい処理がある場合、except節よりも下にelse節を記述することで実行されるようにできる。try: # [失敗して例外名1もしくは例外名2の例外を発生させる可能性のある処理(関数呼び出し)...] except [例外名1] as [例外オブジェクト1]: # [例外名1の例外が発生した場合の処理...] except [例外名2] as [例外オブジェクト2]: # [例外名2の例外が発生した場合の処理...] # ... else: # [いずれの例外も発生しなかった場合の処理...]
例外を起こす
何かの処理の中で、状況によっては(処理を中止しつつ)例外としてそれを通知したいということがある。そういったときにraise文を用いると任意の例外を「起こす」ことができる。その際には例外への引数を付けることもできる。raise [例外名] ([引数...])
ユーザ定義の例外
例外として扱いたい状況が発生したとき、定義済みの例外以外に独自の名前を付けて使用したい場合がある。そうしたときにはExceptionクラスを継承した例外クラスを定義することでユーザ定義の例外を作成できる。下は例。上に書いているelse節やraise文も使用している。[任意]ファイル名: userexceptiontest.py
#! /usr/bin/python # -*- coding: utf-8 -*- from __future__ import print_function import sre_constants import sys import re class PatternNotFoundException (Exception): """ 正規表現パターンが見つからないときに発生させる例外 """ def __init__ (self, instr, ptn): # instrとptnはraise文から受け取る引数 self._instr, self._ptn = (instr, ptn) # メンバ変数に代入 def __str__ (self): # エラーメッセージ return ('Pattern "{0}" not found in "{1}"'.format (self._ptn, self._instr)) class RegexPatternChecker: """ 正規表現パターンのチェックを行うツール """ def __init__ (self, ptn): self._regexobj = re.compile (ptn) self._ptn = ptn def check (self, instr): """ 入力された文字列を正規表現オブジェクトによりチェックして パターンが見つからない場合にPatternNotFoundExceptionを出す """ print ('checking {0} in {1} ... '.format (self._ptn, instr), end='') m = self._regexobj.search (instr) # 見つからない場合に例外を発生するようにする if not m: raise PatternNotFoundException (instr, self._ptn) # 括弧内は引数 # メイン処理 str1 = '<img src="01.jpg" alt="desc" />' str2 = '<img src="02.jpg" />' ptnstr = 'alt="[^"]+"' #ptnstr = '(a' # 不正なパターン文字列のテスト用 try: checker_imgalt = RegexPatternChecker (ptnstr) except sre_constants.error as e: sys.exit ('Invalid regex pattern: "{0}": {1}'.format (ptnstr, e)) # 個別にtry-except-elseでチェックし、結果を表示 try: checker_imgalt.check (str1) except PatternNotFoundException as e: print ('BAD\nPatternNotFoundException: {0}'.format (e)) else: print ('GOOD') try: checker_imgalt.check (str2) except PatternNotFoundException as e: print ('BAD\nPatternNotFoundException: {0}'.format (e)) else: print ('GOOD') print ('-' * 80) # try-exceptがないところで例外が発生したらそこで実行が中止される checker_imgalt.check (str1) print ('GOOD') checker_imgalt.check (str2) # ここで発生 print ('GOOD') # ここには到達しないため下のメッセージは表示されない print ('All OK')
(2009/5/25)不正な正規表現パターン文字列が指定された場合の処理を追加
下は実行結果。線を引いた上の最終行ではtry-exceptにより捉えたときに情報を出力している。線の下のほうでは、2番目の文字列(str2)を処理しているときに例外が捉えられていないためそこで(自動的に)例外の情報や発生位置を表示しつつ終了している。
checking alt="[^"]+" in <img src="01.jpg" alt="desc" /> ... GOOD checking alt="[^"]+" in <img src="02.jpg" /> ... BAD PatternNotFoundException: Pattern "alt="[^"]+"" not found in "<img src="02.jpg" />" -------------------------------------------------------------------------------- checking alt="[^"]+" in <img src="01.jpg" alt="desc" /> ... GOOD checking alt="[^"]+" in <img src="02.jpg" /> ... Traceback (most recent call last): File "[userexceptiontest.pyの場所]", line 69, in <module> checker_imgalt.check (str2) # ここで発生 File "[userexceptiontest.pyの場所]", line 35, in check raise PatternNotFoundException (instr, self._ptn) # 括弧内は引数 __main__.PatternNotFoundException: Pattern "alt="[^"]+"" not found in "<img src="02.jpg" />"
参考URL: