フレームオブジェクトは関数呼び出しの実行コンテキストを表し、コールスタックの情報を保持しています。デバッグやトレースに活用できます。
フレームの取得
import sys
def inner():
frame = sys._getframe()
print(f"Current function: {frame.f_code.co_name}")
print(f"Caller: {frame.f_back.f_code.co_name}")
def outer():
inner()
outer()
sys._getframe() で現在のフレームを取得し、f_back で呼び出し元のフレームを辿れます。
フレームの主要属性
| f_code | コードオブジェクト |
| f_locals | ローカル変数の辞書 |
| f_globals | グローバル変数の辞書 |
| f_back | 呼び出し元のフレーム |
| f_lineno | 現在実行中の行番号 |
| f_lasti | 最後に実行したバイトコードのインデックス |
コールスタックの走査
import sys
def print_stack():
frame = sys._getframe()
while frame:
code = frame.f_code
print(f"{code.co_filename}:{frame.f_lineno} in {code.co_name}")
frame = frame.f_back
def func_a():
func_b()
def func_b():
print_stack()
func_a()
ローカル変数の取得
def debug_locals():
x = 10
y = 20
frame = sys._getframe()
print(frame.f_locals) # {'x': 10, 'y': 20, 'frame': ...}
debug_locals()
inspect モジュールとの連携
import inspect
def show_callers():
for frame_info in inspect.stack():
print(f"{frame_info.function} at line {frame_info.lineno}")
def example():
show_callers()
example()
inspect.stack() は FrameInfo オブジェクトのリストを返し、より安全にスタック情報を取得できます。
注意点
フレームへの参照を保持すると循環参照が発生しやすい
sys._getframe() は CPython 固有で、他の実装では動作しない可能性がある
本番コードでの使用は避け、デバッグ用途に留める
フレームオブジェクトの理解は、デバッガーやプロファイラの実装、例外トレースバックの解析に不可欠です。