2013-04-02 2 views

Répondre

26

Vous pouvez utiliser le module trace:

python -m trace -t your_script.py 

La ligne de commande ci-dessus affichera chaque ligne de code tel qu'il est exécuté.

+0

Merci beaucoup cela fonctionne bien. –

11

pour obtenir une bonne équivalent de bash -x en utilisant le module trace, on a besoin d'utiliser --ignore-dir pour bloquer l'impression de lignes de source de chaque module importé, par exemple python -m trace --trace --ignore-dir /usr/lib/python2.7 --ignore-dir /usr/lib/pymodules repost.py, en ajoutant d'autres directives --ignore-dir selon les besoins pour les autres emplacements de module.

Cela devient important lorsque vous tentez de localiser des modules à chargement lent tels que requests qui crachent des millions de lignes source pendant plusieurs minutes sur une machine lente. l'utilisation correcte de --ignore-dir réduit le temps à quelques secondes et affiche uniquement les lignes de votre propre code.

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

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

contre

$ 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 

cela ne répond pas vraiment à votre question; vous avez demandé un équivalent Python de set -x. une façon simple de rapprocher qui est avec 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() 

qui, lorsqu'il est exécuté, donne:

[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 

éliminant la ligne 'TRACING.pop()' de la sortie de trace est laissée en exercice pour le lecteur.

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

+1

J'écris un petit alias qui exclut tout stdlib par défaut: alias pyx = "python -m trace --ignore-dir $ (python -c 'importe, sys; print (os.pathsep.join ([p pour p dans sys.path si "python3.5" dans p ou "python2.7" dans p])) ') -t " –

+2

Celui-ci est plus court et gère virtualenv sans avoir besoin de re-source: alias pyx =" python -m trace --ignore-dir \ $ (python -c 'importe os, sys; print (os.pathsep.join (sys.path [1:]))') -t " –

+0

Ce serait bien si vous mettez à jour votre réponse travailler aussi avec Python 3 – tjanez

Questions connexes