“sys.settrace”在Python 3.5中是否正常工作但在Python 3.6中不能正常工作?

时间:2017-03-21 16:16:01

标签: python debugging python-3.5 trace python-3.6

在尝试回答另一个问题时,我突然意识到,当理论上不应该控制时,你可以在线程中随时运行代码。 CPython有一个settrace函数,用于在一个代码中注册跟踪函数。为了通过使用类来测试这个想法,编写了以下代码。问题是似乎没有发生跟踪,并且跟踪日志中没有生成数据。导致问题的原因如下所示?

#! /usr/bin/env python3
import atexit
import collections
import pprint
import sys


def main():
    i = create_instance()
    print(len(i.data), flush=True)


def create_instance():
    instance = Tracer()
    return instance


class Tracer:

    def __init__(self):
        self.data = []
        sys.settrace(self.trace)
        atexit.register(pprint.pprint, self.data)
        atexit.register(sys.settrace, None)

    def trace(self, frame, event, arg):
        print('Tracing ...', flush=True)
        self.data.append(TraceRecord(frame, event, arg))
        return self.trace


TraceRecord = collections.namedtuple('TraceRecord', 'frame, event, arg')


if __name__ == '__main__':
    main()

附录:

在Windows上运行Python 3.5时,问题并不明显。但是,在Python 3.6中不会发生跟踪,因此不会打印跟踪日志。如果有人可以为我确认这个错误的答案,那么很有可能会接受提交并获得赏金。

1 个答案:

答案 0 :(得分:1)

我尝试了你的程序,确实发布后它没有任何可追踪的内容。内置函数print()len()不会生成跟踪事件,可能是因为它们是由平台定义的,并且假设它们的内部结构正常且不感兴趣。

文档说明:

  

每当输入新的本地范围时,都会调用跟踪函数(事件设置为'call');

我修改了你的程序来定义一个函数并调用它。当我这样做时,你的跟踪功能就被调用了。

我定义的功能:

def doSomething():
  print("Hello World")

我的main()功能版本:

def main():
  i = create_instance()
  print(len(i.data))
  doSomething()
  print(len(i.data))

我看到的输出:

 0
 Tracing ...
 Tracing ...
 Hello World
 Tracing ...
 3