Pythonでは構文エラーを含めて、大半のエラーを例外の形で取り扱う。そのための機構であるtry文やraise文などについてサンプル多めで見ていこう。
前回まではPythonのモジュール/パッケージ/名前空間とスコープなどについて見てきた。今回はPythonの例外処理の基本を見ていくことにしよう。
Pythonではプログラム実行時に発生するエラー(およびPythonコードの構文解析時に発生するエラー)を例外の形で扱う。最も簡単な例外の例は次のようなものだろう(これはPython Tools for Visual Studio(以下、PTVS)の[Interactive]ウィンドウで実行したものだ)。
上の例では、関数定義内のブロックにインデントを付けていないためにIndentationErrorという例外が発生している。ここで出てきたIndentationErrorクラスは構文エラーを表すSyntaxErrorクラスの派生クラスとなっている。
今見たのはPythonコードの構文解析時に検出される例外だが、プログラム実行時に発生するエラーももちろん例外として取り扱われる。以下に例を示す。
Pythonには多数の例外が組み込みで用意されている。全ての組み込み例外はBaseExceptionクラスから派生する(ユーザー定義の例外クラスも作成でき、その場合はBaseExceptionクラスから派生させずに、Exceptionクラスから派生させることが推奨されている)。実際の例外クラスのクラス階層は以下のようなコードを実行することで一覧表示可能だ(現在の実行コンテキストで定義されている例外を表示する。そのため、[Interactive]ウィンドウでの実行結果と「python 〜」とコマンドラインから実行した場合の結果は異なる)。
def getsubcls(cls, n=0):
if n == 0: # 最初だけ特別にインデントなしでクラス名を表示
print(cls.__name__)
for subcls in cls.__subclasses__(): # 指定されたクラスの派生クラスを反復する
print(' ' * (n+1), subcls.__name__, sep='') # インデント付きでクラス名表示
getsubcls(subcls, n + 1) # そのクラスが派生クラスを持っていればそれらを表示
getsubcls(BaseException)
コードの詳しい解説は省略するが、この関数getsubclsではパラメーターに渡された「クラス」オブジェクトに対して「__subclsses__」メソッドを呼び出し、その派生クラスを取得して、それに対して反復処理を行っている。反復処理内では、個々の派生クラス名の表示(インデント付き)とそのクラスの派生クラスを一覧表示している。[Interactive]ウィンドウでこれを実行すると、例えば次のような結果となる(抜粋。なお、コマンドプロンプトからpythonコマンドで対話環境を起動した場合には、空行の部分で関数定義が終了してしまうかもしれない。その場合は空行を含めないようにしよう)。
>>> def getsubcls(cls, n=0):
... if n == 0:
... print(cls.__name__)
...
... for subcls in cls.__subclasses__():
... print(' ' * (n+1), subcls.__name__, sep='')
... getsubcls(subcls, n + 1)
...
>>> getsubcls(BaseException)
BaseException
Exception
SystemError
CodecRegistryError
MemoryError
Error
… 省略 …
ArithmeticError
FloatingPointError
OverflowError
ZeroDivisionError
LookupError
… 省略 …
EOFError
NameError
… 省略 …
SyntaxError
IndentationError
TabError
… 省略 …
RuntimeError
RecursionError
NotImplementedError
… 省略 …
GeneratorExit
SystemExit
KeyboardInterrupt
上で見たIndentationErrorクラスやZeroDivisionErrorクラスもこの階層に含まれていることが分かる。また、クラスの継承関係をインデントで表現していることにも注意されたい。例えば、IndentationErrorクラスは構文エラー一般を表すSyntaxErrorクラスの派生クラスだ(同様にZeroDivisionErrorクラスはArithmeticErrorクラスの派生クラス)。
例外が発生した場合には、それを処理しない限りはプログラムの実行は中断して、例外の発生箇所を示すスタックトレースと発生した例外の種類が表示される。例外を処理するための構文がtry文である。次ページではこれについて見ていこう。
Copyright© Digital Advantage Corp. All Rights Reserved.