"sys.settrace" 在 Python 3.5 中正常工作但在 Python 3.6 中不正常吗?

Does "sys.settrace" work properly in Python 3.5 but not in Python 3.6?

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

#! /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 上 运行ning Python 3.5 时问题不明显。但是,Python 3.6 中不会出现跟踪,因此不会打印跟踪日志。如果有人可以为我确认该错误是一个很好的答案,那么该提交很有可能会被接受并获得赏金。

我试过你的程序,确实如发布的那样,它没有任何可追踪的东西。内置函数 print()len() 不会生成跟踪事件,大概是因为它们是由平台定义的,并且假设它们的内部工作正常并且没有意义。

文档指出:

The trace function is invoked (with event set to 'call') whenever a new local scope is entered;

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

我定义的函数:

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