在尝试回答另一个问题时,我突然意识到,当理论上不应该控制时,你可以在线程中随时运行代码。 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中不会发生跟踪,因此不会打印跟踪日志。如果有人可以为我确认这个错误的答案,那么很有可能会接受提交并获得赏金。
答案 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