Python inspectとは?オブジェクトの中身を調べる方法を解説
inspectは、実行中のオブジェクトの中身を調べる標準モジュールです。
関数の引数・ソースコード・クラスの構造などをプログラムから取得できます。
何ができるのか
import inspect
def greet(name, greeting="こんにちは"):
"""挨拶を返す。"""
return f"{greeting}、{name}さん"
print(inspect.signature(greet))
print(inspect.getdoc(greet))
print(inspect.isfunction(greet))
実行結果:
(name, greeting='こんにちは')
挨拶を返す。
True
引数の定義・説明文・種類——どれもコードを読まずに取得できています。
主な関数
| 関数 | 取得できるもの |
|---|---|
signature() |
引数の定義 |
getdoc() |
docstring(整形済み) |
getsource() |
ソースコード |
getmembers() |
属性の一覧 |
getfile() |
定義されたファイル |
stack() |
呼び出し履歴 |
さらにis○○()という判定関数が多数あります。
import inspect
import asyncio
async def af(): pass
print("isfunction:", inspect.isfunction(greet))
print("isclass:", inspect.isclass(int))
print("iscoroutinefunction:", inspect.iscoroutinefunction(af))
print("ismethod:", inspect.ismethod(greet))
実行結果:
isfunction: True
isclass: True
iscoroutinefunction: True
ismethod: False
ismethod()がFalseなのは、greetがクラスに属さない普通の関数だからです。メソッドとの区別に使えます。
使いどころ
- デコレータ——引数の定義を保ったまま関数を包む
- プラグイン機構——モジュール内のクラスを自動で集める
- 自動ドキュメント生成——docstringと引数を抽出する
- フレームワーク——引数名を見て値を自動で渡す
- デバッグ——どこから呼ばれたか調べる
4つ目はpytestのfixtureやFastAPIの依存性注入で使われている仕組みです。引数名から必要なものを判断して渡しています。
クラスの中身を調べる
import inspect
class Calc:
"""計算用のクラス"""
version = "1.0"
def add(self, a, b):
return a + b
def sub(self, a, b):
return a - b
for name, obj in inspect.getmembers(Calc, inspect.isfunction):
print(name, inspect.signature(obj))
実行結果:
add (self, a, b)
sub (self, a, b)
第2引数で絞り込めます。これを書かないと__class__などの特殊属性まで大量に出てきます。
詳しくは「Python inspect.getmembers()とは?オブジェクトの中身を一覧する方法」で解説しています。
ソースコードを取得する
import inspect
print(inspect.getsource(greet))
実行結果:
def greet(name, greeting="こんにちは"):
"""挨拶を返す。"""
return f"{greeting}、{name}さん"
定義そのものが文字列で返ります。
ただしファイルが必要です。対話シェルで定義した関数や、組み込み関数には使えません。
inspect.getsource(len)
実行結果:
TypeError: module, class, method, function, traceback, frame, or code object was expected, got builtin_function_or_method
「Python inspect.getsource()とは?ソースコードを取得する方法」を参照してください。
dir()との違い
print(dir(Calc)[:3])
print(inspect.getmembers(Calc)[:1])
実行結果:
['__class__', '__delattr__', '__dict__']
[('__class__', <class 'type'>)]
dir()は名前のリストを返すだけですが、getmembers()は名前と実体のペアを返します。
dir() |
inspect.getmembers() |
|
|---|---|---|
| 戻り値 | 名前だけ | (名前, 実体) |
| 絞り込み | できない | できる |
| 手軽さ | 高い | やや冗長 |
対話的に確認するならdir()、プログラムで処理するならgetmembers()です。
使いすぎない
inspectは強力ですが、注意点があります。
- 処理が重い——ループの中で呼ぶものではない
- 実装に依存する——引数名を変えただけで壊れる
- 読み手に何が起きているか分かりにくい
「引数名を見て自動で処理を分岐する」ようなコードは、動きが追いにくく保守しづらくなります。
設定や引数で明示できるなら、そちらを選んでください。フレームワークを作る側の道具だと考えると、使いどころを誤りません。
inspectのまとめ
- 実行中のオブジェクトの中身をプログラムから調べる
signature()で引数、getdoc()で説明文getsource()はファイルがないと使えないgetmembers()は第2引数で絞り込むdir()は名前だけ、getmembers()は実体つき- 処理は重く、実装に依存する——多用しない



