sys.settrace只在函数调用时调用,而不是每行调用

时间:2015-08-28 18:00:57

标签: python

我在sys.settrace中设置了一个钩子,用于检查当前正在执行的代码对象是否是我的源文件之一(位于C:驱动器中),如果是,则将行号提供给linecache检索该行,然后将其附加到日志文件中。但是当我运行它时,钩子似乎只是在函数调用上被调用而不是像文档所指示的那样。这不是我所期望的,因为在我关注的教程中http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html 我的代码非常相似,但在示例中很清楚每行调用sys.settrace挂钩。

我的跟踪代码:

from __future__ import with_statement
import sys
import re
import linecache


def startTracing():
    sys.settrace(lineHook)

def lineHook(frame, event, arg):
    scriptPath = "C:\MidiScript"
    lineno = frame.f_lineno

    p = re.compile(r"C:\\")
    filename = str(frame.f_code.co_filename)
    if p.match(filename):
        line = linecache.getline(filename, lineno)
        with open("C:\Midi Script\\test.txt", "a") as myfile:
            myfile.write("event: " + str(event) + "\targ: " + str(arg) + "\t" + "line " + str(frame.f_lineno) + ":\tline: " + line + "\n")
    return

一些输出(很多重复):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 115:   line:     def handle_sysex(self, midi_bytes):

event: call arg: None   line 111:   line:     def refresh_state(self):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

event: call arg: None   line 134:   line:     def _send_midi(self, midi_bytes, optimized = None):

2 个答案:

答案 0 :(得分:2)

再次阅读文档,特别是说:

的部分
  

每当输入新的本地范围时,都会调用跟踪函数(事件设置为'call');它应返回对该范围使用的本地跟踪函数的引用,如果不应跟踪该范围,则返回None。

您的跟踪功能始终返回None,因此它不会在任何范围内跟踪。

再次阅读文档以了解如何使用settrace

答案 1 :(得分:0)

来自https://pymotw.com/2/sys/tracing.html

的"本地跟踪功能"的示例

请注意trace_calls如何返回trace_lines

import sys

def trace_lines(frame, event, arg):
    if event != 'line':
        return
    co = frame.f_code
    func_name = co.co_name
    line_no = frame.f_lineno
    filename = co.co_filename
    print '  %s line %s' % (func_name, line_no)

def trace_calls(frame, event, arg):
    if event != 'call':
        return
    co = frame.f_code
    func_name = co.co_name
    if func_name == 'write':
        # Ignore write() calls from print statements
        return
    line_no = frame.f_lineno
    filename = co.co_filename
    print 'Call to %s on line %s of %s' % (func_name, line_no, filename)
    if func_name in TRACE_INTO:
        # Trace into this function
        return trace_lines
    return

def c(input):
    print 'input =', input
    print 'Leaving c()'

def b(arg):
    val = arg * 5
    c(val)
    print 'Leaving b()'

def a():
    b(2)
    print 'Leaving a()'

TRACE_INTO = ['b']

sys.settrace(trace_calls)
a()