2015-08-12 6 views
9

Trace-Modul Python ermöglicht es Ihnen, Drucken jeder Codezeile ein Skript auszuführen, da sie sowohl das Skript in ausgeführt wird und alle importierten Module wie folgt:Wie wird jede Zeile eines Skripts gedruckt, da es nur für das Skript der obersten Ebene ausgeführt wird?

python -m trace -trace myscript.py 

Gibt es eine Möglichkeit, das Gleiche zu tun, aber nur die Top-Level-Anrufe drucken, dh nur die Zeilen in myscript.py drucken, wie sie ausgeführt werden?

Ich versuche, einen Abbruch Trap Fehler zu debuggen und ich kann nicht herausfinden, wo es stirbt. Leider dauert die Verwendung der vollen --trace für immer - das Skript dauert normalerweise 2-3 Minuten, und die vollständige Ablaufverfolgung ist seit Stunden gegangen.

+0

versuchen 'python -m trace --listfuncs --trackcalls meinskript.py'? – luoluo

+0

Luoluo - das zumindest in endlicher Zeit fertig war, aber es ließ mich immer noch mit einem Durcheinander von Tracebacks durchgraben. Und seltsamerweise druckte das Skript selbst nicht alle Zeilen, nur die Importe. – keflavich

+0

Werfen Sie einen Blick darauf: [http://pymotw.com/2/trace/index.html#module-trace](http://pymotw.com/2/trace/index.html#module-trace) – luoluo

Antwort

0

Es ist nicht genau das, was Sie wollen, aber Sie können py.test mit "-s" in Betracht ziehen, was verhindert, dass py.test die Ausgabe Ihrer Druckanweisung erfasst ... So können Sie hier einige Druckanweisungen ablegen dort für jede Funktion, die Sie in Ihrem Skript haben und erstellen Sie einen Dummy-Test, die nur Ihr Skript wie gewohnt ausführen ... Sie können dann sehen, wo es fehlgeschlagen ist.

0

Wenn Sie keine Traceback erhalten, können Sie die Technik Bisektion verwenden.

Bearbeiten Sie Ihre Hauptfunktion oder Skriptkörper und setzen Sie einen exit(1) Anruf etwa in der Mitte. Dies ist die erste Halbierung.

Führen Sie Ihr Skript aus. Wenn es Ihren Ausgang erreicht, wissen Sie, dass der Fehler in der zweiten Hälfte ist. Wenn nicht, ist es in der ersten Hälfte.

Verschieben Sie die 10 auf die Hälfte der ersten Hälfte oder die Hälfte der zweiten Hälfte und versuchen Sie es erneut.

Mit jedem Zyklus können Sie die Position des Fehlers um die Hälfte des verbleibenden Codes verringern.

Wenn Sie es auf eine Ihrer eigenen Funktionen eingeschränkt haben, halbieren Sie das.

+1

Während diese Technik im Allgemeinen nützlich ist, ist es extrem langwierig und scheitert vollständig, wenn es eine for-Schleife und Der Fehler tritt nicht in der ersten Iteration der Schleife auf. Meiner Ansicht nach sollte 'trace' der einfachste Weg sein, dies zu tun * ohne * die Anweisungen' print' oder 'exit' überall fallen zu lassen. – keflavich

0

Sie können Dekorateur verwenden und alle Funktionen Ihres Moduls dynamisch dekorieren (keine Bearbeitung der einzelnen Funktionen). Sie müssen nur diese Zeilen am Ende des Skripts einzufügen:

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

Interessante Idee, aber erfordert dies nicht, dass das Skript vollständig ausgeführt wird, bevor es funktionieren kann, da es 'globals' verwendet, um die Funktionsnamen zu erhalten? – keflavich

+0

Ich weiß es nicht, wir sollten es testen, ich sehe nicht, warum und tatsächlich der Test, den ich gemacht habe, war ein numpy Call, der Python stürzte und ich bekomme den Druck des Funktionsaufrufs, der ausführen und die Spur des numpy Fehler, der Python stürzt. Dieser Absturz numpy: import numpy Import numpy def crash_python_with_numpy(): # Ref: http://stackoverflow.com/questions/5340739/filling-numpy-array-using-crashes-python txtInputs = leer ((7,12), dtype = Objekt) txtInputs [:,:] = '' – Richard

2

ich in dieses Problem gestolpert und fand grep eine quick and dirty Lösung zu sein:

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

Mein Skript obwohl in endlicher Zeit läuft. Dies wird wahrscheinlich nicht gut für komplexere Skripte funktionieren.

Verwandte Themen