2015-08-12 17 views
9

di pitone vi permetterà di eseguire uno script di stampa ogni riga di codice come viene eseguito sia nella sceneggiatura e tutti i moduli importati in questo modo:Come stampare ogni riga di uno script poiché viene eseguita solo per lo script di livello superiore in esecuzione? Modulo traccia

python -m trace -trace myscript.py 

C'è un modo per fare la stessa cosa, ma solo stampare le chiamate di livello superiore, ovvero stampare solo le righe in myscript.py durante l'esecuzione?

Sto tentando di eseguire il debug di un errore di interruzione della trap e non riesco a capire dove sta morendo. Sfortunatamente, l'utilizzo dell'intero --trace richiede sempre: lo script richiede in genere 2-3 minuti e la traccia completa dura da ore.

+0

try 'python -m trace --listfuncs --trackcalls myscript.py'? – luoluo

+0

luoluo - che almeno è stato completato in tempo limitato, ma mi ha lasciato ancora un pasticcio di un traceback da scavare. E, stranamente, per la sceneggiatura stessa, non ha stampato tutte le righe, solo le importazioni. – keflavich

+0

Dai un'occhiata a questo: [http://pymotw.com/2/trace/index.html#module-trace](http://pymotw.com/2/trace/index.html#module-trace) – luoluo

risposta

0

Non è esattamente quello che vuoi, ma puoi prendere in considerazione l'uso di py.test con "-s" che impedirà a py.test di catturare l'output della tua stampa statica ... Quindi puoi mettere un po 'di stampa qui e lì per ogni funzione che hai nel tuo script e creare un test fittizio che esegua il tuo script come al solito ... Puoi quindi vedere dove ha fallito.

0

Se non si ottiene un traceback, è possibile utilizzare la tecnica denominata bisection.

Modificare la funzione principale o il corpo dello script e inserire una chiamata approssimativamente nel mezzo. Questa è la prima bisezione.

Esegui il tuo script. Se raggiunge la tua uscita, sai che il guasto è nella seconda metà. Se no, è nel primo semestre.

Spostare lo exit a metà del primo semestre o metà del secondo semestre e riprovare.

Ad ogni ciclo, è possibile restringere la posizione dell'errore per metà del codice rimanente.

Se lo hai ristretto a una delle tue funzioni, taglia quella.

+1

Mentre questa tecnica è generalmente utile, è estremamente noiosa e fallisce completamente se c'è un ciclo for e l'errore non si verifica nella prima iterazione del ciclo. A mio avviso, 'trace' dovrebbe essere il modo semplice per farlo * senza * rilasciare le istruzioni' print' o 'exit' ovunque. – keflavich

0

È possibile utilizzare decoratore e decorare dinamicamente tutte le funzioni del modulo (nessuna modifica di ciascuna funzione). Hai solo bisogno di incollare queste righe alla fine dello script:

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 
+0

Idea interessante, ma questo non richiede che lo script venga eseguito fino al completamento prima che possa funzionare, dal momento che sta usando 'globals' per acquisire i nomi delle funzioni? – keflavich

+0

Non so, dovremmo testarlo, non vedo perché e in realtà il test, ho fatto includendo una chiamata numpy che stava bloccando python e ottengo la stampa della chiamata di funzione che viene eseguita e la traccia del errore di numpy che crash python. Questo incidente NumPy: import NumPy importazione NumPy def crash_python_with_numpy(): # Rif: http://stackoverflow.com/questions/5340739/filling-numpy-array-using-crashes-python txtInputs = vuoto ((7,12), dtype = oggetto) txtInputs [:,:] = '' – Richard

2

ci siamo imbattuti in questo problema e trovato grep di essere una soluzione rapida e sporca:

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

mio script viene eseguito in un tempo finito però. Questo probabilmente non funzionerà bene per script più complessi.