如何打印脚本的每一行,因为它只运行正在运行的顶级脚本?

时间:2015-08-12 12:04:43

标签: python trace

python的跟踪模块将允许您运行脚本打印每行代码,因为它在脚本和所有导入的模块中运行,如下所示:

 python -m trace -trace myscript.py

有没有办法做同样的事情,但打印顶级调用,即只在myscript.py运行时打印行?

我正在尝试调试中止陷阱失败,我无法弄清楚它在哪里死亡。不幸的是,使用完整的--trace需要永远 - 脚本通常需要2-3分钟才能运行,并且完整的跟踪已持续数小时。

6 个答案:

答案 0 :(得分:8)

我偶然发现了这个问题,发现grep是一个快速而肮脏的解决方案:

python -m trace --trace my_script.py | grep my_script.py

我的脚本在有限的时间内运行。对于更复杂的脚本,这可能不会很好。

答案 1 :(得分:2)

如果只使用一个文件来运行所有代码,但是当使用整个文件项目时,当前接受的答案就足够了。跟踪多个文件的一种方法是通过以下方式手动列出所有文件:

python -m trace --trace src/main.py | grep "main.py\|file2.py"

对于小型项目,这可能就足够了,但对于具有大量文件的大型项目,列出所有必要的文件名可能会很烦人,并且容易出错。以这种方式,理想情况下,您需要为您的文件名构建一个正则表达式,并使用 find 列出您需要监控的所有文件。

按照这个想法,我构建了一个正则表达式,它匹配所有not以较低破折号开头的文件名(以避免匹配__init__.py文件),donot< /strong> 在其名称或文件夹名称中包含任何大写字母,并具有 .py 扩展名。要列出 src 文件夹中的所有文件,请匹配这些条件,命令是:

find src/ -type f -regextype sed -regex '\([a-z_]\+/\)\+[a-z][a-z_]\+.py'

现在为了在 grep 中使用这些文件,我们只需要在它们之间用反斜杠和管道打印它们。要打印该结构中的名称,请使用以下命令:

find src/ -type f -regextype sed -regex '\([a-z_]\+/\)\+[a-z][a-z_]\+.py' -printf '%f\\\\|' | awk '{ print substr ($0, 1, length($0)-3)}'

最后,我们构造命令以将所有文件与跟踪进行匹配:

python -m trace --trace src/main.py | grep "`find src/ -type f -regextype sed -regex '\([a-z_]\+/\)\+[a-z][a-z_]\+.py' -printf '%f\\\\|' | awk '{ print substr ($0, 1, length($0)-3)}'`"

这可用于匹配项目特定文件夹中的文件名,并且可以修改正则表达式以包含您可能拥有的其他重要细节以及您想要监控的文件名。

答案 2 :(得分:1)

也许lptrace对您有用。

答案 3 :(得分:0)

这不完全是你想要的,但是你可以考虑使用py.test和“-s”来阻止py.test捕获你的打印声明的输出......所以你可以在这里和那里放一些打印声明对于脚本中的每个函数,并创建一个像往常一样执行脚本的虚拟测试...然后您可以看到它失败的位置。

答案 4 :(得分:0)

如果您没有获得追溯,您可以使用名为 bisection 的技术。

编辑您的主要功能或脚本正文,并在中间大致地exit调用。这是第一次分裂。

执行你的脚本。如果它到达你的出口,你知道故障是在下半场。如果没有,那就是上半场。

将{{1}}移动到上半场的一半,或下半场的一半,然后重试。

对于每个周期,您可以将故障的位置缩小一半剩余代码。

如果您已将其缩小到自己的某个功能,请将其平分。

答案 5 :(得分:0)

您可以使用装饰器动态地装饰模块的所有功能(不编辑每个功能)。您只需要在脚本末尾粘贴这些行:

def dump_args(func):
    """This decorator dumps out the arguments passed to a function before calling it"""
    argnames = func.func_code.co_varnames[:func.func_code.co_argcount]
    fname = func.func_name
    def echo_func(*args,**kwargs):
        print fname, "(", ', '.join(
            '%s=%r' % entry
            for entry in zip(argnames,args[:len(argnames)])+[("args",list(args[len(argnames):]))]+[("kwargs",kwargs)]) +")"
    return echo_func

### Decorate all the above functions
import types
for k,v in globals().items():
    if isinstance(v, types.FunctionType):
        globals()[k] = dump_args(v)


Reference, code is coming from these two answers :
http://stackoverflow.com/questions/8951787/defining-python-decorators-for-a-complete-module
http://stackoverflow.com/questions/6200270/decorator-to-print-function-call-details-parameters-names-and-effective-values