Получить имя модуля вызывающей функции в Python
предположим myapp/foo.py содержит:
def info(msg):
caller_name = ????
print '[%s] %s' % (caller_name, msg)
и myapp/bar.py содержит:
import foo
foo.info('Hello') # => [myapp.bar] Hello
Я хочу caller_name для установки в __name__ атрибут модуля вызывающих функций (который является " myapp.foo') в данном случае. Как это можно сделать?
3 ответов:
Проверьте модуль проверки:
inspect.stack()вернет информацию о стеке.функции
inspect.stack()[1]вернет стек вашего абонента. Оттуда вы можете получить дополнительную информацию о имени функции вызывающего абонента, модуле и т. д.смотрите документы для получения дополнительной информации:
http://docs.python.org/library/inspect.html
кроме того, у Дуга Хеллмана есть хорошая запись модуля inspect в его PyMOTW серия:
http://pymotw.com/2/inspect/index.html#module-inspect
EDIT: вот некоторый код, который делает то, что вы хотите, я думаю:
def info(msg): frm = inspect.stack()[1] mod = inspect.getmodule(frm[0]) print '[%s] %s' % (mod.__name__, msg)
столкнулся с подобной проблемой, я обнаружил, что sys._current_frames () из модуля sys содержится интересная информация, которая может помочь вам, без необходимости импорта inspect, по крайней мере, в конкретных случаях использования.
>>> sys._current_frames() {4052: <frame object at 0x03200C98>}затем вы можете "двигаться вверх" с помощью 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.f_back.f_code.co_filename, как предложил Марк Родди выше. Я не уверен в ограничения этого метода (несколько потоки скорее всего будут проблемы), но я намерен использовать его в моем случае.
Я не рекомендую делать этого, но вы можете достичь своей цели с помощью следующего метода:
def caller_name(): frame=inspect.currentframe() frame=frame.f_back.f_back code=frame.f_code return code.co_filenameзатем обновите существующий метод следующим образом:
def info(msg): caller = caller_name() print '[%s] %s' % (caller, msg)
Comments