2015-08-28 51 views
1

sys.settrace设置挂钩,会检查当前执行的代码对象是我的源文件(在C:驱动器)之一,如果是这样,给行号为linecache以检索该行,然后将其附加到日志文件。但是当我运行这个钩子时,似乎只能在函数调用中调用,而不是像文档中的每一行都表示。这不是我所期待的,因为在教程中我遵循:http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html 我的代码非常相似,但在该示例中很明显,每行都会调用sys.settrace挂钩。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): 
+0

您是否阅读过[文档](https://docs.python.org/2/library/sys.html#sys.settrace)? – BrenBarn

+0

是的,我只是困惑,为什么它是所有'呼叫'事件,没有'线'。在一个程序中甚至可能如此? –

+0

而'_send_midi'函数有行,它不仅仅是调用。 –

回答

2

再次阅读文档,特别是部分,上面写着:

只要输入新的本地范围,就会调用跟踪功能(事件设置为“调用”);它应该返回一个对使用该范围的本地跟踪函数的引用,或者如果不应跟踪范围,则返回None。

您的跟踪函数总是返回None,因此它不会在任何范围内跟踪。

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

+0

就是这样!非常感谢。 –

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()