Python でプログラミング中に実行中のメソッド名や行番号などオブジェクト情報を取得したいシーンがあると思います。
inspect を使用すれば取得可能なのですが、いまいち使い方が解らない方もいると思います。
本記事では、 inspect の使用方法を Google Colaboratory のサンプルコードを交えて紹介します。
目次
inspect 使用モジュールのサンプルコード
Google Colaboratory を使用して説明します。
まずはじめに、下記記事を参考に、inspect を使用する自作モジュールを用意します。
下記フォルダ構成になるようにします。
「exec.py」は下記をコピペしてください。(__init__.py は空で構いません)
import inspect
class Params:
outerframesindex = 2
_Params = Params()
def setouterframesindex(_idx):
_Params.outerframesindex = _idx
def inspecttest_0():
# 呼び出し元のフレームオブジェクトを返します。
print("4")
print("2")
calframe = inspect.getouterframes(inspect.currentframe(), _Params.outerframesindex)
print("3")
print("5")
print("★★ printinspect:start")
i = 0
for rec in calframe:
if i < 4:
print("~~~")
print(f"{i}階層目のオブジェクト情報を取得します(配列で格納)")
j = 0
for w in rec:
print(f"「{j}」番目の要素を取得します")
print(w)
if j == 1:
fn = w.split("/")
print("######「1」番目の要素に限り配列に変換します ######")
print(fn)
print("########################################")
j += 1
print("~~~")
i += 1
print("★★ printinspect:end")
def inspecttest_1():
print("★ === inspecttest2-4 ===")
print("★ === inspecttest2-2 ===")
inspecttest_0()
print("★ === inspecttest2-3 ===")
print("★ === inspecttest2-5 ===")
def inspecttest_2():
print("★ === inspecttest3-4 ===")
print("★ === inspecttest3-2 ===")
inspecttest_1()
print("★ === inspecttest3-3 ===")
print("★ === inspecttest3-5 ===")
Google Colaboratory からサンプルコードを実行
Google Colaboratory にて下記コードを実行します。
# Googleドライブのマウント
from google.colab import drive
drive.mount('/content/drive')
# カレントディレクトリを「Colab Notebooks/」に変更
import os
_colab_dir = "/content/drive/MyDrive/Colab Notebooks"
os.chdir(_colab_dir)
# InspectTestを実行する
from MyPythonLibrary.InspectTest import exec
exec.setouterframesindex(5)
exec.inspecttest_2()
解説
exec.py の15行目を解説します。
calframe = inspect.getouterframes(inspect.currentframe(), _Params.outerframesindex)
inspect.getouterframes() は、第一引数に指定したフレームとその外側の全フレームのフレームレコードを返します。(フレームとは、その処理が含まれたメソッドに関する情報くらいのイメージで良いと思います)
これはどういうことかと言いますと、フレームを取得したメソッドと、そのメソッドを実行するメソッドを再帰的に取得するということです。
つまり、exec.pyのように、「inspecttest_2() -> inspecttest_1() -> inspecttest_0() 」という順番でメソッドを実行している場合、inspecttest_0()に紐づけて、inspecttest_1() とinspecttest_2()を取得することが出来ます。
また、第二引数には戻り値のソース行リストに何行分のソースを含めるかを指定します。
第二引数の設定例
def inspecttest_1()のソース行リストがどう変わるかを紹介します。
def inspecttest_1():
print("★ === inspecttest2-4 ===")
print("★ === inspecttest2-2 ===")
inspecttest_0()
print("★ === inspecttest2-3 ===")
print("★ === inspecttest2-5 ===")
inspect.getouterframes()の第二引数に”1″を指定した場合
対応するソース行のみが取得出来ていることが解ります。
inspect.getouterframes()の第二引数に”3″を指定した場合
対応するソース行を含む3行が取得出来ていることが解ります。
モジュール名・ファイル名・メソッド名・行番号の取得方法
inspect.getouterframes()を使用するとフレームオブジェクトが配列で取得できます。
配列の各要素を出力すると下記のようになります。
注目すべきは、「1」番目と「2」番目と「3」番目と「4」番目の要素です。
要素番号 | 格納されている情報 |
---|---|
1 | フレームオブジェクトの実行ファイルのフルパス |
2 | 対象の行番号 |
3 | メソッド名 |
4 | ソースコード行 |
モジュール名・ファイル名取得例
# 【A】フレームオブジェクトを取得
calframe = inspect.getouterframes(inspect.currentframe(), 3)
# ①【A】を実行した処理を含むメソッドのモジュール名・ファイル名
fn_0 = calframe[0][1].split("/")
# モジュール名
modulename_0 = fn_0[len(fn_0) - 2]
# ファイル名
filename_0 = fn_0[len(fn_0) - 1]
# ②①を呼び出したメソッドのモジュール名・ファイル名
fn_1 = calframe[1][1].split("/")
# モジュール名
modulename_1 = fn_1[len(fn_1) - 2]
# ファイル名
filename_1 = fn_1[len(fn_1) - 1]
# ③①を呼び出したメソッドのモジュール名・ファイル名
fn_2 = calframe[2][1].split("/")
# モジュール名
modulename_2 = fn_2[len(fn_2) - 2]
# ファイル名
filename_1 = fn_2[len(fn_2) - 1]
# ・・・・
メソッド名の取得例
# 【A】フレームオブジェクトを取得
calframe = inspect.getouterframes(inspect.currentframe(), 3)
# ①【A】を実行した処理を含むメソッドのメソッド名
mname_0 = calframe[0][3]
# ②①を呼び出したメソッドのメソッド名
mname_1 = calframe[1][3]
# ③①を呼び出したメソッドのメソッド名
mname_2 = calframe[2][3]
# ・・・・
行番号の取得例
# 【A】フレームオブジェクトを取得
calframe = inspect.getouterframes(inspect.currentframe(), 3)
# ①【A】を実行した処理の行番号
lineno_0 = calframe[0][2]
# ②①を呼び出した処理の行番号
lineno_1 = calframe[1][2]
# ③①を呼び出した処理の行番号
lineno_2 = calframe[2][2]
# ・・・・
まとめ
本記事では、 本記事では、inspect を使用して Colab で実行中のオブジェクト情報(モジュール名・ファイル名・メソッド名・行番号など)を取得する方法を紹介しました。
ご参考になりましたら twitter をフォローして SNS でシェアして頂ければ幸いです。
また、本記事で紹介した inspect の応用事例についても合わせてご参考ください。