# 28.13. `inspect` --- 活動中のオブジェクトの情報を取得する

バージョン 2.1 で追加.

ソースコード: Lib/inspect.py

`inspect` は、活動中のオブジェクト (モジュール、クラス、メソッド、関数、トレースバック、フレームオブジェクト、コードオブジェクトなど) から情報を取得する関数を定義しており、クラスの内容を調べたり、メソッドのソースコードを取得したり、関数の引数リストを取り出して整形したり、詳細なトレースバックを表示するのに必要な情報を取得したりするために利用できます。

このモジュールの機能は4種類に分類することができます。型チェック、ソースコードの情報取得、クラスや関数からの情報取得、インタープリタのスタック情報の調査です。

## 28.13.1. 型とメンバー

`getmembers()` は、クラスやモジュールなどのオブジェクトからメンバーを取得します。名前が"is"で始まる16個の関数は、主に `getmembers()` の第2引数として利用するために提供されています。以下のような特殊属性を参照できるかどうか調べる時にも使えるでしょう:

型 | 属性 | 説明 | 注釈
--- | --- | --- | ---
モジュール | __doc__ | ドキュメント文字列 |
| __file__ | ファイル名 (組み込みモジュールには存在しません) |
クラス | __doc__ | ドキュメント文字列 |
| __module__ | クラスを定義しているモジュールの名前 |
メソッド | __doc__ | ドキュメント文字列 |
| __name__ | メソッドが定義された時の名前 |
| im_class | このメソッドを要求したクラスオブジェクト | (1)
| im_func または __func__ | メソッドを実装している関数オブジェクト |
| im_self または __self__ | メソッドに結合しているインスタンス、または `None` |
function | __doc__ | ドキュメント文字列 |
| __name__ | 関数が定義された時の名前 |
| func_code | 関数をコンパイルしたバイトコード (bytecode) を格納するコードオブジェクト |
| func_defaults | 引数のデフォルト値のタプル |
| func_doc | (__doc__ と同じ) |
| func_globals | 関数を定義した時のグローバル名前空間 |
| func_name | (__name__ と同じ) |
generator | __iter__ | コンテナを通したイテレーションのために定義されます |
| close | イテレーションを停止するために、ジェネレータの内部で GeneratorExitexception を発生させます |
| gi_code | コードオブジェクト |
| gi_frame | フレームオブジェクト。ジェネレータが終了したあとは `None` になることもあります |
| gi_running | ジェネレータが実行中の時は 1 それ以外の場合は 0 |
| next | コンテナから次の要素を返します |
| send | ジェネレータを再開して、現在の yield 式の結果となる値を "送り" ます |
| throw | ジェネレータ内部で例外を発生させるために用います |
トレースバック | tb_frame | このレベルのフレームオブジェクト |
| tb_lasti | 最後に実行しようとしたバイトコード中のインストラクションを示すインデックス |
| tb_lineno | 現在の Python ソースコードの行番号 |
| tb_next | このオブジェクトの内側 (このレベルから呼び出された) のトレースバックオブジェクト |
frame | f_back | 外側 (このフレームを呼び出した) のフレームオブジェクト |
| f_builtins | このフレームで参照している組み込み名前空間 |
| f_code | このフレームで実行しているコードオブジェクト |
| f_exc_traceback | このフレームで例外が発生した場合にはトレースバックオブジェクト、それ以外なら `None` |
| f_exc_type | このフレームで例外が発生した場合には例外型、それ以外なら `None` |
| f_exc_value | このフレームで例外が発生した場合には例外の値、それ以外なら `None` |
| f_globals | このフレームで参照しているグローバル名前空間 |
| f_lasti | 最後に実行しようとしたバイトコード中のインストラクションを示すインデックス |
| f_lineno | 現在の Python ソースコードの行番号 |
| f_locals | このフレームで参照しているローカル名前空間 |
| f_restricted | 制限実行モードなら1、それ以外なら0 |
| f_trace | このフレームのトレース関数、または `None` |
コード | co_argcount | 引数の数 (* や ** 引数は含まない) |
| co_code | コンパイルされたバイトコードそのままの文字列 |
| co_consts | バイトコード中で使用している定数のタプル |
| co_filename | コードオブジェクトを生成したファイルのファイル名 |
| co_firstlineno | Python ソースコードの先頭行 |
| co_flags | 以下の値の組み合わせ: 1=optimized `|` 2=newlocals `|` 4=*arg `|` 8=**arg |
| co_lnotab | 行番号からバイトコードインデックスへの変換表を文字列にエンコードしたもの |
| co_name | コードオブジェクトが定義されたときの名前 |
| co_names | ローカル変数名のタプル |
| co_nlocals | ローカル変数の数 |
| co_stacksize | 必要とされる仮想マシンのスタックスペース |
| co_varnames | 引数名とローカル変数名のタプル |
builtin | __doc__ | ドキュメント文字列 |
| __name__ | 関数、メソッドの元々の名前 |
| __self__ | メソッドが結合しているインスタンス、または `None` |

注釈:

1. バージョン 2.2 で変更: `im_class` は、以前はメソッドを定義しているクラスを指していました。

`inspect.``getmembers`(object[, predicate])

  オブジェクトの全メンバーを、(名前, 値) の組み合わせのリストで返します。リストはメンバー名でソートされています。predicate が指定されている場合、predicate の戻り値が真となる値のみを返します。

  注釈

  `getmembers()` は、引数がクラスの場合にメタクラス属性を返しません (この動作は `dir()` 関数に合わせてあります)。

`inspect.``getmoduleinfo`(path)

  path で指定したファイルがモジュールであれば、そのモジュールが Python でどのように解釈されるかを示す `(name, suffix, mode, module_type)` のタプルを返します。モジュールでなければ `None` を返します。 name はパッケージ名を含まないモジュール名、 suffix はファイル名からモジュール名を除いた残りの部分 (ドット区切りの拡張子であってはなりません)、 mode は `open()` で指定されるファイルモード (`'r'` または `'rb'`)、 module_type はモジュールタイプを示す整数で、 `imp` で定義している定数のいずれかが指定されます。モジュールタイプについては `imp` を参照してください。

  バージョン 2.6 で変更: 名前付きタプル (named tuple) の `ModuleInfo(name, suffix, mode, module_type)` を返します。

`inspect.``getmodulename`(path)

  path で指定したファイルの、パッケージ名を含まないモジュール名を返します。この処理は、インタープリタがモジュールを検索する時と同じアルゴリズムで行われます。ファイルがこのアルゴリズムで見つからない場合には `None` が返ります。

`inspect.``ismodule`(object)

  オブジェクトがモジュールの場合は真を返します。

`inspect.``isclass`(object)

  オブジェクトが、ビルトインもしくは Python で作られたクラスの場合に真を返します。

`inspect.``ismethod`(object)

  オブジェクトが Python で実装された束縛メソッドもしくは非束縛メソッドの場合は真を返します。

`inspect.``isfunction`(object)

  オブジェクトが Python の関数(lambda 式で生成されたものを含む) である場合に真を返します。

`inspect.``isgeneratorfunction`(object)

  object が Python のジェネレータ関数であるときに真を返します。

  バージョン 2.6 で追加.

`inspect.``isgenerator`(object)

  object がジェネレータであるときに真を返します。

  バージョン 2.6 で追加.

`inspect.``istraceback`(object)

  オブジェクトがトレースバックの場合は真を返します。

`inspect.``isframe`(object)

  オブジェクトがフレームの場合は真を返します。

`inspect.``iscode`(object)

  オブジェクトがコードの場合は真を返します。

`inspect.``isbuiltin`(object)

  オブジェクトが組み込み関数か束縛済みのビルトインメソッドの場合に真を返します。

`inspect.``isroutine`(object)

  オブジェクトがユーザ定義か組み込みの関数またはメソッドの場合は真を返します。

`inspect.``isabstract`(object)

  object が抽象規定型 (ABC) であるときに真を返します。

  バージョン 2.6 で追加.

`inspect.``ismethoddescriptor`(object)

  オブジェクトがメソッドデスクリプタであり、 `ismethod()`, `isclass()`, `isfunction()`, `isbuiltin()` でない場合に真を返します。

  この機能は Python 2.2 から新たに追加されたもので、例えば `int.__add__` は真になります。 このテストをパスするオブジェクトは `__get__()` メソッドを持ちますが `__set__()` メソッドを持ちません。 それ以外の属性を持っているかもしれません。 通常 `__name__` 属性を持っていますし、たいていは `__doc__` も持っています。

  デスクリプタを使って実装されたメソッドで、上記のいずれかのテストもパスしているものは、 `ismethoddescriptor()` では偽を返します。これは単に他のテストの方がもっと確実だからです -- 例えば、 `ismethod()` をパスしたオブジェクトは `im_func` 属性などを持っていると期待できます。

`inspect.``isdatadescriptor`(object)

  オブジェクトがデータデスクリプタの場合に真を返します。

  データデスクリプタは `__get__` および `__set__` 属性の両方を持ちます。データデスクリプタの例は (Python 上で定義された) プロパティや getset やメンバーです。後者のふたつは C で定義されており、個々の型に特有のテストも行います。そのため、Python の実装よりもより確実です。通常、データデスクリプタは `__name__` や `__doc__` 属性を持ちます (プロパティ、 getset 、メンバーは両方の属性を持っています) が、保証されているわけではありません。

  バージョン 2.3 で追加.

`inspect.``isgetsetdescriptor`(object)

  オブジェクトが getset デスクリプタの場合に真を返します。

  getset とは、拡張モジュールで `PyGetSetDef` 構造体を用いて定義された属性のことです。そのような型を持たない Python 実装の場合は、このメソッドは常に `False` を返します。

  バージョン 2.5 で追加.

`inspect.``ismemberdescriptor`(object)

  オブジェクトがメンバーデスクリプタの場合に真を返します。

  メンバーデスクリプタとは、拡張モジュールで `PyMemberDef` 構造体を用いて定義された属性のことです。そのような型を持たない Python 実装の場合は、このメソッドは常に `False` を返します。

  バージョン 2.5 で追加.

## 28.13.2. ソースコードの情報取得

`inspect.``getdoc`(object)

  `cleandoc()` でクリーンアップされた、オブジェクトのドキュメンテーション文字列を取得します。

`inspect.``getcomments`(object)

  オブジェクトがクラス、関数、メソッドのいずれかの場合は、オブジェクトのソースコードの直後にあるコメント行 (複数行) を、単一の文字列として返します。オブジェクトがモジュールの場合、ソースファイルの先頭にあるコメントを返します。

`inspect.``getfile`(object)

  オブジェクトを定義している (テキストまたはバイナリの) ファイルの名前を返します。オブジェクトが組み込みモジュール、クラス、関数の場合は `TypeError` 例外が発生します。

`inspect.``getmodule`(object)

  オブジェクトを定義しているモジュールを推測します。

`inspect.``getsourcefile`(object)

  オブジェクトを定義している Python ソースファイルの名前を返します。オブジェクトが組み込みのモジュール、クラス、関数の場合には、 `TypeError` 例外が発生します。

`inspect.``getsourcelines`(object)

  オブジェクトのソース行のリストと開始行番号を返します。引数にはモジュール、クラス、メソッド、関数、トレースバック、フレーム、コードオブジェクトを指定することができます。戻り値は指定したオブジェクトに対応するソースコードのソース行リストと元のソースファイル上での開始行となります。ソースコードを取得できない場合は `IOError` が発生します。

`inspect.``getsource`(object)

  オブジェクトのソースコードテキストを返します。引数にはモジュール、クラス、メソッド、関数、トレースバック、フレーム、コードオブジェクトを指定することができます。ソースコードは単一の文字列で返します。ソースコードを取得できない場合は `IOError` が発生します。

`inspect.``cleandoc`(doc)

  コードブロックと位置を合わせるためのインデントを docstring から削除します。

  先頭行の行頭の空白文字は全て削除されます。 2行目以降では全行で同じ数の行頭の空白文字が、削除できるだけ削除されます。 その後、先頭と末尾の空白行が削除され、全てのタブが空白に展開されます。

  バージョン 2.6 で追加.

## 28.13.3. クラスと関数

`inspect.``getclasstree`(classes[, unique])

  リストで指定したクラスの継承関係から、ネストしたリストを作成します。ネストしたリストには、直前の要素から派生したクラスが格納されます。各要素は長さ2のタプルで、クラスと基底クラスのタプルを格納しています。unique が真の場合、各クラスは戻り値のリスト内に一つだけしか格納されません。真でなければ、多重継承を利用したクラスとその派生クラスは複数回格納される場合があります。

`inspect.``getargspec`(func)

  Python 関数の引数名とデフォルト値を取得します。戻り値は長さ4のタプルで、次の値を返します: `(args, varargs, keywords, defaults)` 。 args は引数名のリストです (ネストしたリストが格納される場合があります)。 varargs と keywords は `*` 引数と `**` 引数の名前で、引数がなければ `None` となります。 defaults は引数のデフォルト値のタプルか、デフォルト値がない場合は `None` です。このタプルに n 個の要素があれば、各要素は args の後ろから n 個分の引数のデフォルト値となります。

  バージョン 2.6 で変更: `ArgSpec(args, varargs, keywords, defaults)` 形式の名前付きタプル (named tuple) を返します。

`inspect.``getargvalues`(frame)

  指定したフレームに渡された引数の情報を取得します。戻り値は長さ4のタプルで、次の値を返します: `(args, varargs, keywords, locals)`. args は引数名のリストです (ネストしたリストが格納される場合があります)。 varargs と keywords は `*` 引数と `**` 引数の名前で、引数がなければ `None` となります。 locals は指定したフレームのローカル変数の辞書です。

  バージョン 2.6 で変更: `ArgInfo(args, varargs, keywords, locals)` 形式の名前付きタプル (named tuple) を返します。

`inspect.``formatargspec`(args[, varargs, varkw, defaults, formatarg, formatvarargs, formatvarkw, formatvalue, join])

  `getargspec()` で取得した4つの値を読みやすく整形します。 format* 引数はオプションで、名前と値を文字列に変換する整形関数を指定することができます。

`inspect.``formatargvalues`(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue, join])

  `getargvalues()` で取得した4つの値を読みやすく整形します。 format* 引数はオプションで、名前と値を文字列に変換する整形関数を指定することができます。

`inspect.``getmro`(cls)

  cls クラスの基底クラス (cls 自身も含む) を、メソッドの優先順位順に並べたタプルを返します。結果のリスト内で各クラスは一度だけ格納されます。メソッドの優先順位はクラスの型によって異なります。非常に特殊なユーザ定義のメタクラスを使用していない限り、cls が戻り値の先頭要素となります。

`inspect.``getcallargs`(func[, *args][, **kwds])

  args と kwds を、Python の関数もしくはメソッド func を呼び出した場合と同じように引数名に束縛します。束縛済みメソッド(bound method)の場合、最初の引数(慣習的に `self` という名前が付けられます)にも、関連づけられたインスタンスを束縛します。引数名 (`*` や `**` 引数が存在すればその名前も) に args と kwds からの値をマップした辞書を返します。func を正しく呼び出せない場合、つまり `func(*args, **kwds)` がシグネチャの不一致のために例外を投げるような場合には、それと同じ型で同じか似ているメッセージの例外を発生させます。例:

      >>> from inspect import getcallargs
      >>> def f(a, b=1, *pos, **named):
      ...     pass
      >>> getcallargs(f, 1, 2, 3)
      {'a': 1, 'named': {}, 'b': 2, 'pos': (3,)}
      >>> getcallargs(f, a=2, x=4)
      {'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()}
      >>> getcallargs(f)
      Traceback (most recent call last):
      ...
      TypeError: f() takes at least 1 argument (0 given)

  バージョン 2.7 で追加.

## 28.13.4. インタープリタスタック

以下の関数には、戻り値として"フレームレコード"を返す関数があります。"フレームレコード"は長さ6のタプルで、以下の値を格納しています: フレームオブジェクト、ファイル名、実行中の行番号、関数名、コンテキストのソース行のリスト、ソース行のリストにおける実行中の行のインデックス。

注釈

フレームレコードの最初の要素などのフレームオブジェクトへの参照を保存すると、循環参照になってしまう場合があります。循環参照ができると、Python の循環参照検出機能を有効にしていたとしても関連するオブジェクトが参照しているすべてのオブジェクトが解放されにくくなり、明示的に参照を削除しないとメモリ消費量が増大する恐れがあります。

参照の削除を Python の循環参照検出機能にまかせることもできますが、 `finally` 節で循環参照を解除すれば確実にフレーム (とそのローカル変数) は削除されます。また、循環参照検出機能は Python のコンパイルオプションや `gc.disable()` で無効とされている場合がありますので注意が必要です。例:

    def handle_stackframe_without_leak():
        frame = inspect.currentframe()
        try:
            # do something with the frame
        finally:
            del frame

以下の関数でオプション引数 context には、戻り値のソース行リストに何行分のソースを含めるかを指定します。ソース行リストには、実行中の行を中心として指定された行数分のリストを返します。

`inspect.``getframeinfo`(frame[, context])

  フレームまたはトレースバックオブジェクトの情報を取得します。フレームレコードの最後の 5 要素からなる長さ 5 のタプルを返します。

  バージョン 2.6 で変更: `Traceback(filename, lineno, function, code_context, index)` 形式の名前付きタプル (named tuple) を返します。

`inspect.``getouterframes`(frame[, context])

  指定したフレームと、その外側の全フレームのフレームレコードを返します。外側のフレームとは frame が生成されるまでのすべての関数呼び出しを示します。戻り値のリストの先頭は frame のフレームレコードで、末尾の要素は frame のスタックにある最も外側のフレームのフレームレコードとなります。

`inspect.``getinnerframes`(traceback[, context])

  指定したフレームと、その内側の全フレームのフレームレコードを返します。内のフレームとは frame から続く一連の関数呼び出しを示します。戻り値のリストの先頭は traceback のフレームレコードで、末尾の要素は例外が発生した位置を示します。

`inspect.``currentframe`()

  呼び出し元のフレームオブジェクトを返します。

  この関数はインタプリタの Python スタックフレームサポートに依存します。これは Python のすべての実装に存在している保証はありません。Python スタックフレームサポートのない環境では、この関数は `None` を返します。

`inspect.``stack`([context])

  呼び出し元スタックのフレームレコードのリストを返します。最初の要素は呼び出し元のフレームレコードで、末尾の要素はスタックにある最も外側のフレームのフレームレコードとなります。

`inspect.``trace`([context])

  実行中のフレームと処理中の例外が発生したフレームの間のフレームレコードのリストを返します。最初の要素は呼び出し元のフレームレコードで、末尾の要素は例外が発生した位置を示します。