shell中`set -x`的Python等价物是什么?

Man*_*v G 31 python debugging shell

请建议Python命令,它等同set -x于shell脚本.

有没有办法打印/记录Python执行的每个源文件行?

Fré*_*idi 30

您可以使用跟踪模块:

python -m trace -t your_script.py
Run Code Online (Sandbox Code Playgroud)

上面的命令行将显示执行时的每一行代码.

  • 很好的答案,但这会产生大量的输出。我会做类似“python -m trace -t your_script.py |”的事情 grep your_script.py`,或者它调用的任何您关心执行跟踪的文件。 (4认同)
  • 我在 bash -x 中似乎不喜欢做的一件事是在运行行时查看变量解析为什么。有一个开关吗? (3认同)

jco*_*ctx 18

为了获得bash -x使用trace模块的适当等效,需要使用--ignore-dir来阻止导入的每个模块的源行的打印,例如python -m trace --trace --ignore-dir /usr/lib/python2.7 --ignore-dir /usr/lib/pymodules repost.py,--ignore-dir根据需要为其他模块位置添加更多指令.

这在尝试定位慢速加载模块时变得很重要,例如requests在慢速机器上吐出数百万条源线几分钟.正确使用--ignore-dir将时间缩短到几秒钟,并仅显示您自己代码中的行.

$ time python -m trace --trace repost.py 2>&1 | wc
3710176 16165000 200743489

real    1m54.302s
user    2m14.360s
sys 0m1.344s
Run Code Online (Sandbox Code Playgroud)

与

$ time python -m trace --trace --ignore-dir /usr/lib/python2.7 --ignore-dir /usr/lib/pymodules repost.py 2>&1 | wc
     42     210    2169

real    0m12.570s
user    0m12.421s
sys 0m0.108s
Run Code Online (Sandbox Code Playgroud)

这并没有真正回答你的问题; 你问过Python的等价物set -x.一种简单的近似方法是sys.settrace():

jcomeau@aspire:/tmp$ cat test.py
#!/usr/bin/python -OO
'''
test program for sys.settrace
'''
import sys, linecache
TRACING = []

def traceit(frame, event, arg):
    if event == "line":
        lineno = frame.f_lineno
        line = linecache.getline(sys.argv[0], lineno)
        if TRACING:
            print "%d: %s" % (lineno, line.rstrip())
    return traceit

def test():
    print 'this first line should not trace'
    TRACING.append(True)
    print 'this line and the following ought to show'
    print "that's all folks"
    TRACING.pop()
    print 'this last line should not trace'

if __name__ == '__main__':
    sys.settrace(traceit)
    test()
Run Code Online (Sandbox Code Playgroud)

在运行时,它给出:

jcomeau@aspire:/tmp$ ./test.py
this first line should not trace
19:     print 'this line and the following ought to show'
this line and the following ought to show
20:     print "that's all folks"
that's all folks
21:     TRACING.pop()
this last line should not trace
Run Code Online (Sandbox Code Playgroud)

从跟踪输出中删除"TRACING.pop()"行是留给读者的练习.

来源:https://pymotw.com/2/sys/tracing.html和http://www.dalkescientific.com/writingings/diary/archive/2005/04/20/tracing_python_code.html

  • 我写了一个默认排除所有 stdlib 的小别名: alias pyx="python -m trace --ignore-dir $(python -c 'import os, sys; print(os.pathsep.join([p for p in sys .path 如果 p 中的“python3.5”或 p 中的“python2.7”]))') -t" (2认同)
  • 这是一个短,处理的virtualenv,而不需要重新源:别名PYX ="蟒蛇-m跟踪 - 忽略DIR\$(蟒蛇-c"进口操作系统,SYS;打印(os.pathsep.join(SYS.路径[1:]))') - t" (2认同)