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?

  • Django: manage.py druckt keine Stack-Trace für Fehler
  • Wie kann ich einen Stacktrace in meine Django 500.html Seite einfügen?
  • Rekursion innerhalb einer Variablen durchgeführt
  • Wie kann ich sagen, ob eine Funktion in einer Schleife in der Python-Tracer-Funktion aufgerufen wird?
  • Zeigt den Stack-Trace aus einer laufenden Python-Anwendung an
  • Drucken Sie den aktuellen Anrufstapel aus einer Methode im Python-Code
  • Einen Python-Traceback ohne Ausnahme bekommen
  • Wie bekomme ich die Stack-Trace von einem Exception-Objekt in Python?
  • 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.