Frage

Es sei 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 mag caller_name zum __name__ Attribute der anrufenden Funktion eingestellt wird Modul (das ist ‚in diesem Fall myapp.foo‘). Wie kann dies geschehen?

War es hilfreich?

Lösung

Schauen Sie sich die inspizieren Modul:

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

Innerhalb einer Funktion, inspect.stack()[1] Ihren Anrufer Stapel zurück. Von dort können Sie weitere Informationen über die Anrufer-Funktion Namen, Modul, usw. erhalten.

Lesen Sie die Dokumentation für Details:

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

Auch Doug Hellmann hat eine nette Zuschreibung des inspizieren Modul in seiner PyMOTW Serie:

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

EDIT: Hier ist ein Code, der tut, was Sie wollen, denke ich:

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

Andere Tipps

Konfrontiert mit einem ähnlichen Problem, habe ich festgestellt, dass sys._current_frames () aus dem Modul sys interessanten Informationen enthält, die Ihnen, ohne die Notwendigkeit, zumindest in bestimmten Anwendungsfällen untersuchen, um zu importieren helfen können .

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

Sie können dann "nach oben" mit f_back:

>>> f = sys._current_frames().values()[0]
>>> # for python3: f = list(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 die Dateinamen können Sie auch f.f_back.f_code.co_filename verwenden, wie oben von Mark Roddy vorgeschlagen. Ich bin nicht sicher, ob die Grenzen und Einschränkungen dieser Methode (mehrere Threads werden höchstwahrscheinlich ein Problem sein), aber ich beabsichtige, es in meinem Fall zu verwenden.

ich nicht empfehlen dies zu tun, aber Sie können Ihr Ziel mit dem folgenden Verfahren erreichen:

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

Dann aktualisieren Sie Ihre bestehende Methode wie folgt:

def info(msg):
    caller = caller_name()
    print '[%s] %s' % (caller, msg)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top