Pythonコードをトレースし、ローカル変数値への変更のレポートを出力するプログラムを作成しようとしています。単純な割り当て、ループ、および関数呼び出しでうまく機能していますが、import
ステートメントを使用すると問題が発生します。
メインモジュールのコードのみをトレースしたいのですが、インポートされたモジュールが呼び出されたらすぐにトレースを停止したいと思います。これは、作成した単純なモジュールをインポートするときに実行できます。フレームのコードオブジェクトが別のファイルを指している場合は、トレースを停止します。
ただし、decimal
モジュールをインポートしようとすると、これは機能しません。モジュールで実行されているコードのほとんどを削除できますが、メインモジュールで実行されていると主張するdecimal
コードブロックへの呼び出しが1つあります。DecimalTuple
ただし、そのモジュールには行番号が存在しないため、これは意味がありません。
フレームまたはコードオブジェクトDecimalTuple
に、メインモジュールにないことを伝えるために使用できる他の属性はありますか?もちろん、の特殊なケースを追加することもできDecimalTuple
ますが、他のモジュールで同じ問題が発生した場合は役に立ちません。
これが私の例です。引用符で囲まれたコードを実行し、。を使用して呼び出しをトレースしますsettrace()
。コメントアウトすると、最初の2行global_trace()
に、他のモジュールで実行されるすべてのコードも表示されます。
import sys
class tracer:
count = 0
def __init__(self):
self.index = tracer.count = tracer.count + 1
def global_trace(self, frame, event, arg):
if frame.f_code.co_filename != '<string>':
return
print 'global %d, line %d: %s, %s' % (self.index,
frame.f_lineno,
event,
frame.f_code)
return tracer().local_trace
def local_trace(self, frame, event, arg):
print 'local %d, line %d: %s, %s' % (self.index,
frame.f_lineno,
event,
frame.f_code)
return self.local_trace
code = """\
def foo(r):
return r + 3
y = foo(2)
import decimal
x = decimal.Decimal('10')
"""
sys.settrace(tracer().global_trace)
exec code in dict()
これがトレース出力です。の呼び出しfoo()
とその実行はすべて<string>
、メインモジュールとして渡したコードの文字列を表すモジュール内にあることがわかります。ただし、6行目のimportステートメントに到達すると、モジュールに含まれていない可能性のあるコードの呼び出しを開始し<string>
ます。
global 1, line 1: call, <code object <module> at 0x266a030, file "<string>", line 1>
local 2, line 1: line, <code object <module> at 0x266a030, file "<string>", line 1>
local 2, line 4: line, <code object <module> at 0x266a030, file "<string>", line 1>
global 1, line 1: call, <code object foo at 0x266a730, file "<string>", line 1>
local 3, line 2: line, <code object foo at 0x266a730, file "<string>", line 1>
local 3, line 2: return, <code object foo at 0x266a730, file "<string>", line 1>
local 2, line 6: line, <code object <module> at 0x266a030, file "<string>", line 1>
global 1, line 1: call, <code object <module> at 0x27c2130, file "<string>", line 1>
local 4, line 1: line, <code object <module> at 0x27c2130, file "<string>", line 1>
global 1, line 1: call, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 1: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 2: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 4: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 6: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 8: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 12: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 13: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 20: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 24: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 28: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 30: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 37: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 41: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 42: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 43: line, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 5, line 43: return, <code object DecimalTuple at 0x27c21b0, file "<string>", line 1>
local 4, line 1: return, <code object <module> at 0x27c2130, file "<string>", line 1>
local 2, line 8: line, <code object <module> at 0x266a030, file "<string>", line 1>
local 2, line 8: return, <code object <module> at 0x266a030, file "<string>", line 1>