Erhalten Sie __name__ des Models der Aufruffunktion in Python

Angenommen, myapp/foo.py enthält:

 def info(msg): caller_name = ???? print '[%s] %s' % (caller_name, msg) 

Und myapp/bar.py enthält:

 import foo foo.info('Hello') # => [myapp.foo] Hello 

Ich möchte, dass caller_name auf das Attribut __name__ des aufrufenden Funktionsmoduls (in diesem Fall 'myapp.foo') gesetzt wird. Wie kann man das machen?

  • Wie man Traceit benutzt, um Funktions-Eingangsvariablen im Stack-Trace zu melden
  • Django: manage.py druckt keine Stack-Trace für Fehler
  • Wie kann ich sagen, ob eine Funktion in einer Schleife in der Python-Tracer-Funktion aufgerufen wird?
  • Wie kann ich einen Stacktrace in meine Django 500.html Seite einfügen?
  • Zeigt den Stack-Trace aus einer laufenden Python-Anwendung an
  • Druck-Python-Stack-Trace ohne Ausnahme ausziehen
  • Wie bekomme ich Wert von Argumenten an Funktionen auf dem Stack übergeben?
  • Einen Python-Traceback ohne Ausnahme bekommen
  • 3 Solutions collect form web for “Erhalten Sie __name__ des Models der Aufruffunktion in Python”

    Schauen Sie sich das Inspektionsmodul an:

    inspect.stack() gibt die Stack-Informationen zurück.

    Innerhalb einer Funktion, inspect.stack()[1] wird der Stapel deines Anrufers zurückgegeben. Von dort aus können Sie weitere Informationen über den Funktionsnamen des Anrufers, das Modul usw. erhalten.

    Siehe die docs für Details:

    http://docs.python.org/library/inspect.html

    Auch Doug Hellmann hat in seiner PyMOTW-Serie ein schönes Schreiben des Inspektionsmoduls:

    http://pymotw.com/2/inspect/index.html#module-inspect

    EDIT: Hier ist ein Code, was tut was du willst, denke ich:

     def info(msg): frm = inspect.stack()[1] mod = inspect.getmodule(frm[0]) print '[%s] %s' % (mod.__name__, msg) 

    Mit einem ähnlichen Problem konfrontiert, habe ich festgestellt, dass sys._current_frames () aus dem Sys-Modul enthält interessante Informationen, die Ihnen helfen können, ohne die Notwendigkeit, Inspektion, zumindest in bestimmten Anwendungsfällen zu importieren.

     >>> sys._current_frames() {4052: <frame object at 0x03200C98>} 

    Mit "f_back" kannst du dann "nach oben"

     >>> f = sys._current_frames().values()[0] >>> print f.f_back.f_globals['__file__'] '/base/data/home/apps/apricot/1.6456165165151/caller.py' >>> print f.f_back.f_globals['__name__'] '__main__' 

    Für den Dateinamen kannst du auch f.f_back.f_code.co_filename verwenden, wie von Mark Roddy oben vorgeschlagen. Ich bin mir nicht sicher über die Grenzen und Vorbehalte dieser Methode (mehrere Threads werden höchstwahrscheinlich ein Problem sein), aber ich beabsichtige, es in meinem Fall zu benutzen.

    Ich empfehle dies nicht, aber Sie können Ihr Ziel mit der folgenden Methode erreichen:

     def caller_name(): frame=inspect.currentframe() frame=frame.f_back.f_back code=frame.f_code return code.co_filename 

    Dann aktualisiere deine bestehende Methode wie folgt:

     def info(msg): caller = caller_name() print '[%s] %s' % (caller, msg) 
    Python ist die beste Programmiersprache der Welt.