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.bar] Hello
Ich möchte in diesem Fall caller_name
auf das __name__
Attribut des aufrufenden Funktionsmoduls (myapp.foo) gesetzt werden. Wie kann das gemacht werden?
python
stack-trace
introspection
Sridhar Ratnakumar
quelle
quelle
caller_name
kann es daher nicht sein__main__
Antworten:
Überprüfen Sie das Inspektionsmodul:
inspect.stack()
gibt die Stapelinformationen zurück.Gibt innerhalb einer Funktion
inspect.stack()[1]
den Stapel Ihres Anrufers zurück. Von dort erhalten Sie weitere Informationen über den Funktionsnamen, das Modul usw. des Anrufers.Einzelheiten finden Sie in den Dokumenten:
http://docs.python.org/library/inspect.html
Außerdem hat Doug Hellmann eine schöne Beschreibung des Inspektionsmoduls in seiner PyMOTW-Serie:
http://pymotw.com/2/inspect/index.html#module-inspect
EDIT: Hier ist ein Code, der macht, was Sie wollen, denke ich:
quelle
__name__
Attribut dieses Moduls mithilfe desinspect
Moduls? Wie komme ich beispielsweise in meinem obigen Beispiel zurückmyapp.foo
(nichtmyapp/foo.py
)? Ich habe bereits vor dem Posten bei SO versucht, das Inspect-Modul zu verwenden.inspect.stack()[2]
für den echten Anrufer zugreifen müssen, wenn die Anruferfunktion dekoriert ist (@ ...) .Angesichts eines ähnlichen Problems habe ich festgestellt, dass sys._current_frames () aus dem sys-Modul interessante Informationen enthält, die Ihnen helfen können, Inspektion zumindest in bestimmten Anwendungsfällen zu importieren.
Sie können dann mit f_back "aufsteigen":
Für den Dateinamen können Sie auch f.f_back.f_code.co_filename verwenden, wie oben von Mark Roddy vorgeschlagen. Ich bin mir der Grenzen und Einschränkungen dieser Methode nicht sicher (mehrere Threads werden höchstwahrscheinlich ein Problem sein), aber ich beabsichtige, sie in meinem Fall zu verwenden.
quelle
sys._getframe(1)
, als ihn aufzurufensys._current_frames()
(übrigens, der für jeden Thread eine Frame-Zuordnung zurückgibt).inspect.currentframe()
stattsys._current_frames().values()[0]
.Ich empfehle dies nicht, aber Sie können Ihr Ziel mit der folgenden Methode erreichen:
Aktualisieren Sie dann Ihre vorhandene Methode wie folgt:
quelle
__name__