2013-04-02 9 views

risposta

26

È possibile utilizzare il modulo trace:

python -m trace -t your_script.py 

La riga di comando sopra visualizzerà ogni riga di codice come viene eseguito.

+0

Grazie mille funziona bene. –

11

per ottenere una corretta equivalente bash -x utilizzando il modulo trace, bisogna usare --ignore-dir per bloccare la stampa di linee di source di ogni modulo importate, ad esempio python -m trace --trace --ignore-dir /usr/lib/python2.7 --ignore-dir /usr/lib/pymodules repost.py, aggiungendo altre direttive --ignore-dir necessarie per altre posizioni dei moduli.

Questo diventa importante quando si tenta di individuare moduli a caricamento lento come requests che sputano milioni di righe di origine per diversi minuti su una macchina lenta. l'uso corretto di --ignore-dir riduce il tempo a pochi secondi e mostra solo le righe del proprio codice.

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

real 1m54.302s 
user 2m14.360s 
sys 0m1.344s 

vs.

$ 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 

questo in realtà non rispondere alla tua domanda; hai chiesto un equivalente Python di set -x. un modo semplice per approssimare cioè con sys.settrace():

[email protected]:/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() 

che, quando eseguito, dà:

[email protected]:/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 

eliminando la linea 'TRACING.pop()' dall'uscita di traccia viene lasciata come esercizio per il lettore.

fonti: https://pymotw.com/2/sys/tracing.html e http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html

+1

Scrivo un piccolo alias che esclude tutti gli stdlib di default: alias pyx = "python -m trace --ignore-dir $ (python -c 'import os, sys; print (os.pathsep.join ([p per p in sys.path se "python3.5" in p o "python2.7" in p])) ') -t " –

+2

Questo è più corto e gestisce virtualenv senza necessità di ri-origine: alias pyx =" python -m trace --ignore-dir \ $ (python -c 'import os, sys; print (os.pathsep.join (sys.path [1:]))') -t " –

+0

Sarebbe bello se avessi aggiornato la tua risposta lavorare anche con Python 3 – tjanez

Problemi correlati