为了为我的代码构建专门的调试器,我想跟踪代码中的一些函数,并记录它们在每次调用中收到的参数。
我希望能够做到这一点,而无需向每个函数添加代码行,甚至无需在所有函数周围添加装饰器,而是在整个运行过程中设置跟踪。
这有点类似于 sys 模块中的 sys.settrace 所做的事情: https://docs.python.org/2/library/sys.html
除了据我所知,跟踪不包括函数的参数。
所以我想写一个看起来像这样的函数:
def tracing_func(func_name, args):
if func_name in ['func', 'foo']:
log_func_args(func_name, args)
其中 log_func_args 将其记录在文件中以供以后分析。
然后设置此函数,以便在调用我的代码中的任何函数时调用该函数,并使用函数的名称和参数。
这可以吗?
好吧,sys.settrace 的效果很好:
https://docs.python.org/2/library/sys.html#sys.settrace
还有一个例子:
https://pymotw.com/2/sys/tracing.html
请注意,传递给 settrace 的函数必须返回对其自身的引用(或返回到另一个函数以在该范围内进一步跟踪)。
python-hunter
。可以就地配置,也可以通过设置环境变量来神奇地配置。我刚刚从cookbook编译的一些脚本:
~/bin/ptrace
:
#!/usr/bin/env bash
PYTHONHUNTER="Q(stdlib=False),\
~Q(kind='line'),\
~Q(filename_contains='site-packages'),\
Q(filename_contains='$(pwd)'),\
action=CallPrinter(force_colors=True)" \
"$@"
像这样执行:
pip3 install --user hunter
$ ptrace ./traceme.py
./traceme.py:0 call => <module>()
./traceme.py:37 call => MyClass()
./traceme.py:39 return <= MyClass: None
./traceme.py:46 call => main()
./traceme.py:43 call => foo(arg=10)
./traceme.py:44 return <= foo: '10'
10
./traceme.py:39 call => my_method(self=<__main__.MyClass object at 0x7f0c65646510>, arg=10, keyword=None)
./traceme.py:41 return <= my_method: '10 and None'
10 and None
['./traceme.py']
./traceme.py:49 return <= main: None
./traceme.py:52 return <= <module>: None