我正在尝试编写一个程序,该程序将跟踪 Python 代码并打印本地变量值更改的报告。我可以很好地处理简单的赋值、循环和函数调用,但是当我使用import
语句时遇到了问题。
我只想跟踪主模块中的代码,我想在它调用导入的模块时立即停止跟踪。当我导入一个我编写的简单模块时,我可以做到这一点,当框架的代码对象指向不同的文件时,我就停止跟踪。
decimal
但是,当我尝试导入模块时,这不起作用。我可以消除模块中运行的大部分代码decimal
,但是我调用了一个名为的代码块,该代码块DecimalTuple
声称在主模块中运行。但是,这没有任何意义,因为该模块中不存在行号。
框架或代码对象上是否还有其他一些属性可以用来判断它们DecimalTuple
不在主模块中?显然,我可以为 . 添加一个特殊情况DecimalTuple
,但如果其他模块有同样的问题,这对我没有帮助。
这是我的例子。它执行引用的代码并使用 跟踪调用settrace()
。如果您注释掉它的前两行,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>