代码之家  ›  专栏  ›  技术社区  ›  JPC

为什么输入代码块时没有调用事件?

  •  0
  • JPC  · 技术社区  · 6 年前

    我正在使用Python的 sys.settrace 跟踪程序分析任务的代码执行。

    相比之下 documentation 表示我在输入代码块时未看到注册的调用事件。

    我使用的样本示踪剂如下:

    class BasicTracer(object):
        def __init__(self, fun):
            self.fun = fun
            self.result_acc = []
            self.orig_tracer = None
    
        def trace(self, frame, event, arg):
            self.result_acc.append((event, self.fun(frame)))
            return self.trace
    
        def setup(self):
            self.orig_tracer = sys.gettrace()
            sys.settrace(self.trace)
    
        def shutdown(self):
            sys.settrace(self.orig_tracer)
    
        def run(self, file_path):
            if not os.path.exists(file_path):
                with open('_instrumented.py', 'w') as f:
                    f.write(file_path)
                    file_path = '_instrumented.py'
            src = open(file_path, 'r').read()
            # compile, execute instrumented version
            namespace = {
                '__name__'      : '__main__',
                '__file__'      : file_path,
                '__builtins__'  : __builtins__,
            }
            compiled = compile(src, filename=file_path, mode='exec')
            self.frame_acc = []
            self.result_acc = []
            self.setup()
            exec(compiled, namespace)
            self.shutdown()
    

    例如,考虑源代码:

    src = """
    x = 1
    while x < 3:
      x += 1
    """
    

    我在退出时看到预期的返回事件 while 主体,但进入时没有调用事件。我错过什么了吗?

    import inspect
    tracer = BasicTracer(lambda x: inspect.getframeinfo(x).code_context)
    tracer.run(src)
    tracer.result_acc
    [('call', ['x = 1\n']),
     ('line', ['x = 1\n']),
     ('line', ['while x < 3:\n']),
     ('line', ['  x += 1\n']),
     ('line', ['while x < 3:\n']),
     ('line', ['  x += 1\n']),
     ('line', ['while x < 3:\n']),
     ('return', ['while x < 3:\n']),
     ('call', ['    def shutdown(self):\n']),
     ('line', ['        sys.settrace(self.orig_tracer)\n'])]
    

    如果相关的话,我正在Mac OSX上使用Python 3.6.3。

    1 回复  |  直到 6 年前
        1
  •  3
  •   user2357112    6 年前

    这些文件措词不当。他们说 'call' 事件发生时

    调用函数(或输入其他代码块)。

    但“其他代码块”指的是任何有自己代码的东西 对象 和相关范围,而不是像 while