Python:如何跟踪大型项目中函数的执行顺序

14

我想要追踪Scrapy框架中函数/类的执行顺序。在默认项目中有多个*.py文件,我想知道哪个py文件和类被按顺序执行。在每个类和函数中放置记录器似乎很傻。如何可视化这个顺序?

cprofile主要用于测量总时间。我也可以可视化一个模块内部的执行顺序,这是常见问题,但可视化多个模块则很困难。

关于trace包,我没有找到适用于像Scrapy或Django这样的大型项目的示例。跟踪使用教程仅讲解单个Python文件的情况。

我想要追踪大型项目中多个模块中的多个*.py文件,例如Scrapy,而不仅仅是一个模块。

我知道像pdb这样的调试工具,但我觉得在整个项目中设置断点很麻烦。更重要的是,它不容易概括执行顺序。

最后我通过使用Hunter解决了这个问题,它比内置的trace模块更好。Trace模块并未提供include_dir属性。

对于那些好奇如何追踪所有Scrapy代码行的人。

$PYTHONHUNTER='Q(module_startswith=["scrapy", "your_project"])' scrapy list 


就Django而言,跟踪rest_framework执行代码并保存到test.log中,例如:

$PYTHONHUNTER='Q(module_startswith=["rest_framework", "your_project"]), action=CallPrinter(stream=open("test.log", "w"))' python manage.py runserver --noreload --nothreading

你正在寻找 Python Call Graph 吗?Python Call Graph 是一个 Python 模块,用于为 Python 应用程序创建调用图可视化。 - H.Tibat
2个回答

15

跟踪

trace 模块允许你跟踪程序执行过程,生成带注释的代码覆盖率报告,打印调用者/被调用者关系并列出程序运行期间执行的函数。它可以在另一个程序中使用,也可以通过命令行调用。

python -m trace --count -C . somefile.py ...

上述代码将执行somefile.py,并在当前目录中生成所有Python模块的带注释列表。

PDB

Pdb模块为Python程序定义了一个交互式源代码调试器。它支持在源代码行级别设置(条件)断点和单步调试、堆栈帧检查、源代码列表和在任何堆栈帧的上下文中评估任意Python代码等功能。它还支持事后调试,并可在程序控制下调用。

最常用的命令:

w(here)

  • 打印堆栈跟踪,最近的帧在底部。箭头指示当前帧,决定大多数命令的上下文。

d(own)

  • 将当前帧在堆栈跟踪中向下移动一级(到新帧)。

u(p)

  • 将当前帧在堆栈跟踪中向上移动一级(到旧帧)。

您还可以查看这个问题:Python调试技巧

Coverage

Coverage.py可以在测试执行期间测量代码覆盖率。它使用Python标准库中提供的代码分析工具和跟踪钩子来确定哪些行是可执行的,哪些已经被执行。

Hunter

Hunter是一个灵活的代码跟踪工具包,不是用于测量覆盖率,而是用于调试、日志记录、检查和其他不良目的。

默认操作是仅打印正在执行的代码。例如:

import hunter
hunter.trace(module='posixpath')

import os
os.path.join('a', 'b')

终端输出结果: Hunter Result in terminal


我想追踪一个大型项目中多个模块中的多个*.py文件,例如Scrapy框架,而不仅仅是一个模块。 - anonymous
你想从你的项目代码中找到什么信息? - H.Tibat
2
Hunter很棒。经过几天尝试不同的工具,我发现Hunter已经足够好了。谢谢。 - anonymous

9

追踪函数执行顺序的最佳工具肯定是viztracer。我必须说,可视化对于理解更大的项目来说是一个巨大的因素。

enter image description here

一个像这样的交互式图片,相比于冷冰冰的终端ASCII,使得理解程序中正在发生的事情变得更加容易。
此外,它是一种非侵入式的工具,这意味着您不需要编写任何代码。只需安装它并使用它运行您的程序即可。
pip install viztracer
viztracer your_script.py

另一个重要因素是,viztracer支持多线程和多进程,并且可以将它们在同一时间轴上用单独的信号进行可视化,这是您无法通过终端显示实现的。

1
我试过了,这是一个非常好的工具。非常感谢。 - Albert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接