我在 python 中有一个开源项目的源代码,该项目有一个模块(python)和 gui,使用该模块 gui 是用 qtpython 编写的,现在在使用 gui 并在其中执行各种操作时,我有什么办法可以知道被调用的函数是什么以及从哪里调用日志之类的东西,有什么方法可以生成源代码的 uml 图,以便我可以更好地理解它并为项目做出贡献。项目使用的 python 版本是 2.7
2 回答
正如评论中提到的,从 Python 生成 UML 已经在这个答案中讨论过。(请记住,Python 实际上不必是 UML 可表示的,但如果是,那就太好了。)
至于在运行时查看控制流,有几种方法可以做到这一点。一种是使用分析和/或调试工具。但是让我们看一下最简单的记录方法,这就是您所要求的:
您可以随时通过print
ing 到控制台“记录”任何内容。您将不得不从命令行运行该应用程序,而不是以 GUI 样式启动它(在 Mac 上,这意味着您必须直接运行可执行文件/脚本,而不是任何.app
由它构建的包),然后您'已经得到了你的日志输出——cmd
如果你愿意的话,你可以使用你的 shell(甚至是 Windows )将它重定向到一个文件以供以后浏览。如果这对您来说还不够好,请参阅logging
标准库中内置的模块。
如果您想知道从哪里调用函数,可以在每次调用函数时记录堆栈跟踪。这有点难看,但它提供了您可能想要的所有信息,并且您总是可以编写一些代码来稍后解析输出。函数traceback.print_stack正是这样做的。(如果您想更花哨,请使用其他功能来提取信息,根据需要格式化,并根据需要记录。)
为此,您可以将此行添加到要跟踪的每个函数中:
traceback.print_stack()
另一种方法是编写一个猴子修补程序并将其应用于您关心的所有功能:
def tracify(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
traceback.print_stack()
func(*args, **kwargs)
return wrapper
现在,在主脚本中,只需执行以下操作:
InterestingClass.interestingMethod = tracify(InterestingClass.interestingMethod)
现在,每次调用 InterestingClass.interestingMethod 时,它都会打印出一个堆栈跟踪。您不必了解其tracify
工作原理。如果你想改变它对函数的作用,只需用traceback.print_stack()
你想做的任何东西替换该行。
那么,如果你想修补类中的每个“公共”方法怎么办?
for attr in dir(InterestingClass):
if not attr.startswith('_'):
method = getattr(InterestingClass, attr)
if isinstance(method, instancemethod):
setattr(InterestingClass, tracify(method))
(这是针对 Python 2 的。Python 3 改变了事情,使复杂的情况变得更加简单,但琐碎的情况却没有那么琐碎。)
如果您想修补模块中每个类的每个公共方法和每个自由函数怎么办?您可以以相同的方式迭代模块,并检查每个事物的类型,就像您可以使用类一样。
你也可以使用检查模块为你做一些困难的事情。但如果你只是学习 Python,我认为复制和粘贴dir
代码比学习如何使用inspect
. 一旦你对这种语言更加熟悉了,就回来inspect
尝试一下,找出它为什么会奏效。
我不使用 Python,但是当您想实时跟踪程序正在做什么时,您可以使用调试器,并且对 Python 调试器进行一些谷歌搜索可能会给您一些有希望的结果。