Aktuelle Aufrufliste aus einer Methode im Code drucken

Lesezeit: 5 Minuten

Benutzer-Avatar
man selbst

Wie kann ich in Python die aktuelle Aufrufliste aus einer Methode heraus drucken (für Debugging-Zwecke).

Benutzer-Avatar
Richie Hindle

Hier ist ein Beispiel für das Abrufen des Stacks über die zurück verfolgen Modul, und drucken Sie es:

import traceback

def f():
    g()

def g():
    for line in traceback.format_stack():
        print(line.strip())

f()

# Prints:
# File "so-stack.py", line 10, in <module>
#     f()
# File "so-stack.py", line 4, in f
#     g()
# File "so-stack.py", line 7, in g
#     for line in traceback.format_stack():

Wenn Sie den Stapel wirklich nur auf stderr drucken möchten, können Sie Folgendes verwenden:

traceback.print_stack()

Oder um auf stdout zu drucken (nützlich, wenn die umgeleitete Ausgabe zusammengehalten werden soll), verwenden Sie:

traceback.print_stack(file=sys.stdout)

Aber immer per traceback.format_stack() lässt Sie damit machen, was Sie wollen.

  • So machen Sie dasselbe für alle anderen Threads (Ich spreche von Threads, die ich nicht kontrolliere) ?

    – Benutzer2284570

    10. Februar 2017 um 3:40 Uhr

  • Vielleicht fehlt mir hier etwas, aber Sie rufen f an, dessen einziger Zweck hier darin besteht, g anzurufen, und tut nichts anderes. Warum

    – Chris

    27. April 2017 um 3:37 Uhr

  • @Chris: Es ist nur ein Beispiel. Es hat mehrere Funktionen, um zu verdeutlichen, dass format_stack() alle Aufrufe auf dem Stack druckt.

    – Richie Hindle

    27. April 2017 um 6:09 Uhr

  • Wenn Sie eine ausführlichere Ausgabe (einschließlich Vars usw.) erhalten möchten, lesen Sie diese verwandte Frage und diese.

    – Albert

    7. Oktober 2018 um 12:47 Uhr


  • @ user2284570: Sie können verwenden sys._current_frames(). Z.B py_better_exchook dump_all_thread_tracebacks tut das (Haftungsausschluss: Ich habe das geschrieben).

    – Albert

    7. Oktober 2018 um 12:50 Uhr

import traceback
traceback.print_stack()

  • Eigentlich mag ich traceback.print_exc() was Ihnen fast dasselbe gibt, was Sie ohne bekommen hätten except Anweisung (und ist auch weniger codierend als die akzeptierte Antwort).

    – Martinau

    4. November 2010 um 19:23 Uhr

  • traceback.print_exc() druckt den Stack-Trace für jede Ausnahme, die Sie möglicherweise behandeln – aber dies löst nicht die ursprüngliche Frage, wie die ausgegeben wird aktuell Stack (“wo Sie jetzt sind” im Gegensatz zu “wo Ihr Code war, als die letzte Ausnahme ausgelöst wurde, falls vorhanden”.)

    – Tom Swirly

    27. Februar 2013 um 22:42 Uhr

  • Es kann sinnvoll sein, den Trace auf eine Anzahl von Einträgen zu beschränken, zB: traceback.print_stack(limit=4)

    – David

    3. Februar 2021 um 9:20 Uhr


inspect.stack() gibt den aktuellen Stapel anstelle des Ausnahme-Tracebacks zurück:

import inspect
print inspect.stack()

Sehen https://gist.github.com/FredLoney/5454553 für eine log_stack-Hilfsfunktion.

für diejenigen, die den Aufrufstapel drucken müssen, während sie pdb verwenden, tun Sie es einfach

(Pdb) where

Wenn Sie den Python-Debugger verwenden, können Sie nicht nur Variablen interaktiv untersuchen, sondern auch die Aufrufliste mit dem Befehl “where” oder “w” abrufen.

Also ganz oben auf Ihrem Programm

import pdb

Dann in den Code, wo Sie sehen möchten, was passiert

pdb.set_trace()

und Sie werden in eine Eingabeaufforderung fallen gelassen

  • Ich programmiere seit über einem Jahrzehnt in Python. Es gibt Also oft hätte ich das gebrauchen können! Ich kann nicht glauben, dass ich es erst jetzt herausfinde.

    – hosford42

    14. April 2017 um 15:42 Uhr

  • Wie hängt das zusammen where?

    – Nikodaemus

    19. Juni 2018 um 18:03 Uhr

  • Um den “Wo”-Teil der Frage zu beantworten: Nachdem Sie die pdb-Eingabeaufforderung erhalten haben (pdb) Tipp einfach where und es wird den Stack-Trace an das Terminal drucken.

    – stephenmm

    10. Oktober 2018 um 17:08 Uhr

  • Python 3.7 und höher haben eine eingebaute Funktion breakpoint() was den Import von pdb überflüssig macht.

    – Benutzer650654

    12. Juni 2019 um 23:43 Uhr

  • Ein Hinweis für alle, die dies in einem Jupyter-Notebook ausprobieren: Geben Sie exit() in die Eingabeaufforderung ein, damit die Zelle die Ausführung beendet.

    – Schermann

    11. März um 1:59

Benutzer-Avatar
Martineau

Hier ist eine Variation der hervorragenden Antwort von @RichieHindle, die einen Decorator implementiert, der nach Wunsch selektiv auf Funktionen angewendet werden kann. Funktioniert mit Python 2.7.14 und 3.6.4.

from __future__ import print_function
import functools
import traceback
import sys

INDENT = 4*' '

def stacktrace(func):
    @functools.wraps(func)
    def wrapped(*args, **kwds):
        # Get all but last line returned by traceback.format_stack()
        # which is the line below.
        callstack = '\n'.join([INDENT+line.strip() for line in traceback.format_stack()][:-1])
        print('{}() called:'.format(func.__name__))
        print(callstack)
        return func(*args, **kwds)

    return wrapped

@stacktrace
def test_func():
    return 42

print(test_func())

Ausgabe von Beispiel:

test_func() called:
    File "stacktrace_decorator.py", line 28, in <module>
    print(test_func())
42

  • Ich programmiere seit über einem Jahrzehnt in Python. Es gibt Alsooft hätte ich das gebrauchen können! Ich kann nicht glauben, dass ich es erst jetzt herausfinde.

    – hosford42

    14. April 2017 um 15:42 Uhr

  • Wie hängt das zusammen where?

    – Nikodaemus

    19. Juni 2018 um 18:03 Uhr

  • Um den “Wo”-Teil der Frage zu beantworten: Nachdem Sie die pdb-Eingabeaufforderung erhalten haben (pdb) Tipp einfach where und es wird den Stack-Trace an das Terminal drucken.

    – stephenmm

    10. Oktober 2018 um 17:08 Uhr

  • Python 3.7 und höher haben eine eingebaute Funktion breakpoint() was den Import von pdb überflüssig macht.

    – Benutzer650654

    12. Juni 2019 um 23:43 Uhr

  • Ein Hinweis für alle, die dies in einem Jupyter-Notebook ausprobieren: Geben Sie exit() in die Eingabeaufforderung ein, damit die Zelle die Ausführung beendet.

    – Schermann

    11. März um 1:59

Installieren Inspiziere es

pip3 install inspect-it --user

Code

import inspect;print(*['{:40}| {}:{}\n'.format(x.function, x.filename, x.lineno) for x in inspect.stack()])

Sie können einen Ausschnitt dieser Zeile erstellen

Es zeigt Ihnen eine Liste der Funktionsaufrufstapel mit Dateiname und Zeilennummer

Liste von Anfang an, wo Sie diese Zeile einfügen

1098400cookie-checkAktuelle Aufrufliste aus einer Methode im Code drucken

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy