Python 如何使用sys.settrace跟踪在全局范围内运行的代码?

Python 如何使用sys.settrace跟踪在全局范围内运行的代码?,python,Python,假设我有这样一段代码: import sys def printer(frame, event, arg): print(frame, event, arg) return printer sys.settrace(printer) x = 1 sys.settrace(None) 自 每当输入新的本地作用域时,就会调用跟踪函数(将事件设置为“调用”) 上述代码不输出任何内容。见我以前的照片 那么有没有一种方法可以在全局范围内跟踪行,比如x=1?sys.settrace设置

假设我有这样一段代码:

import sys

def printer(frame, event, arg):
    print(frame, event, arg)
    return printer

sys.settrace(printer)
x = 1
sys.settrace(None)

每当输入新的本地作用域时,就会调用跟踪函数(将事件设置为“调用”)

上述代码不输出任何内容。见我以前的照片


那么有没有一种方法可以在全局范围内跟踪行,比如
x=1

sys.settrace
设置全局跟踪函数。此跟踪函数是在输入新的Python堆栈帧(
'call'
事件)时调用的函数,其返回值是新范围的本地跟踪函数。活动堆栈帧的本地跟踪函数用于所有其他事件类型

您需要设置现有堆栈帧的本地跟踪函数,但设置全局跟踪函数无助于您这样做。要设置现有帧的本地跟踪函数,可以手动将帧对象的
f_trace
属性指定给所需的函数。例如,要设置当前帧的本地跟踪函数:

import sys
sys._getframe().f_trace = whateverfunc
请注意,如果没有全局跟踪函数,则不会调用本地跟踪函数,因此您也需要设置全局跟踪函数。(这似乎没有记录在案。)


您可以组合
sys.settrace
和手动
f_trace
分配来跟踪新的和现有的堆栈帧;例如,在
'return'
事件中,可以检查要返回的帧的本地跟踪函数,并将该跟踪函数设置为所需的任何值。这是如何使用跟踪函数的一个很好的示例。

谢谢。我使用
sys.\u getframe().f\u trace=printer
替换了
sys.settrace(printer)
,仍然没有得到任何输出。我有什么误解吗?@laike9m:你还需要设置全局跟踪功能。如果没有全局跟踪函数,则不会调用本地跟踪函数。这是Python调试支持的一个奇怪的、未记录的细节。哇,太疯狂了,非常感谢。。。是:这种行为发生在哪里?@laike9m:这是其中的一个重要部分。也很重要,尤其是
trace\u trampoline
,这是一个C级跟踪函数,与传递给
settrace
的Python级函数不同,用于本地和全局跟踪函数调用。在
ceval.c
中对
call\u trace
按Ctrl-F-ing键也会显示一组相关代码。