特集
» 2017年01月13日 05時00分 UPDATE

特集:Visual Studioで始めるPythonプログラミング:Pythonの例外をサクサク理解しよう (1/4)

Pythonでは構文エラーを含めて、大半のエラーを例外の形で取り扱う。そのための機構であるtry文やraise文などについてサンプル多めで見ていこう。

[かわさきしんじ,Insider.NET編集部]
「特集:Visual Studioで始めるPythonプログラミング」のインデックス

連載目次

 前回まではPythonのモジュール/パッケージ/名前空間とスコープなどについて見てきた。今回はPythonの例外処理の基本を見ていくことにしよう。

Pythonの例外

 Pythonではプログラム実行時に発生するエラー(およびPythonコードの構文解析時に発生するエラー)を例外の形で扱う。最も簡単な例外の例は次のようなものだろう(これはPython Tools for Visual Studio(以下、PTVS)の[Interactive]ウィンドウで実行したものだ)。

インデントを間違えているので、IndentationError例外が発生した インデントを間違えているので、IndentationError例外が発生した

 上の例では、関数定義内のブロックにインデントを付けていないために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文である。次ページではこれについて見ていこう。

       1|2|3|4 次のページへ

Copyright© 1999-2017 Digital Advantage Corp. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。