【问题标题】:Tracing fIle path and line number跟踪文件路径和行号
【发布时间】:2013-02-01 01:03:23
【问题描述】:

我正在使用 python 的trace 模块来跟踪一些代码。当我以这种方式跟踪代码时,我可以获得以下两个结果之一:

致电

tracer = trace.Trace(count=False, trace=True, ignoredirs=[sys.prefix, sys.exec_prefix])
r = tracer.run('run()')
tracer.results().write_results(show_missing=True)

结果

<filename>(<line number>): <line of code>

致电 [citation]:

tracer = trace.Trace(count=False, trace=True, ignoredirs=[sys.prefix, sys.exec_prefix], countfuncs=True)
r = tracer.run('run()')
tracer.results().write_results(show_missing=True)

结果

filename:<filepath>, modulename:<module name>, funcname: <function name>

我真正需要的是一个可以给我这个的踪迹:

<filepath> <line number>

似乎我可以使用上述信息并将它们交错以获得我需要的东西,但在以下用例中这样的尝试会失败:

  • sys.path 包含目录A 和目录B
  • 有两个文件A/foo.pyB/foo.py
  • A/foo.pyB/foo.py 都包含函数 bar,定义在第 100 - 120 行
  • A/foo.pyB/foo.py 之间存在一些细微差别

在这种情况下,如果不静态分析每个bar 中的代码,就不可能使用这种交错来正确识别调用了哪个bar(如果我错了请纠正我),这对于非琐碎的功能。

那么,我怎样才能获得我需要的正确跟踪输出?

【问题讨论】:

  • 你解决过这个问题吗?我也有同样的问题。
  • 不幸的是,我最终没有遇到这个问题。我认为@aquavitae 的解决方案可能会奏效。让我知道这是否为您解决了问题,以便我可以接受该答案
  • 我找到了一个与@aquavitae 的解决方案大致相同的解决方案:破解跟踪模块。 stackoverflow.com/questions/20947780/…

标签: python python-2.7 trace filepath


【解决方案1】:

通过一点猴子补丁,这实际上很容易。深入研究trace 模块的源代码,似乎回调用于报告每个执行步骤。 Trace.run 的基本功能,大大简化后是:

sys.settrace(globaltrace)   # Set the trace callback function
exec function               # Execute the function, invoking the callback as necessary
sys.settrace(None)          # Reset the trace

globaltraceTrace.__init__ 中定义,具体取决于传递的参数。具体来说,使用第一个示例中的参数,Trace.globaltrace_lt 用作全局回调,它为每一行执行调用 Trace.localtrace_trace。更改它只是修改Trace.localtrace的情况,所以要得到你想要的结果:

import trace
import sys
import time
import linecache

class Trace(trace.Trace):
    def localtrace_trace(self, frame, why, arg):
        if why == "line":
            # record the file name and line number of every trace
            filename = frame.f_code.co_filename
            lineno = frame.f_lineno

            if self.start_time:
                print '%.2f' % (time.time() - self.start_time),
            print "%s (%d): %s" % (filename, lineno,
                                  linecache.getline(filename, lineno)),
        return self.localtrace


tracer = Trace(count=False, trace=True, ignoredirs=[sys.prefix, sys.exec_prefix])
r = tracer.run('run()')

你给出的两个例子是有区别的;如果第一个输出在Trace.run 调用期间打印,则在第二个输出在write_results 期间打印。我上面给出的代码遵循前者的模式,所以tracer.results().write_results() 不是必需的。但是,如果您想操作此输出,可以通过以类似方式修补 trace.CoverageResults.write_results 方法来实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多