Как я могу получить доступ к текущему исполняющему модулю или имени класса в Python?

Я хотел бы иметь возможность динамически извлекать текущий исполняемый модуль или имя класса из импортированного модуля. Вот какой код:

foo.py:

def f(): print __name__ 

bar.py:

 from foo import f def b(): f() 

Это, очевидно, не работает, поскольку __name__ – это имя модуля, содержащего эту функцию. То, что я хотел бы получить в модуле foo – это имя текущего исполняемого модуля, который использует foo . Поэтому в приведенном выше примере это будет bar но если какой-либо другой модуль импортирует foo я бы хотел, чтобы foo динамически имел доступ к имени этого модуля.

Изменить: модуль inspect выглядит довольно многообещающим, но это не совсем то, что я искал. На что я надеялся, была какая-то глобальная переменная или переменная уровня среды, к которой я мог получить доступ, которая будет содержать имя текущего исполняемого модуля. Не то, чтобы я не хотел проходить стек, чтобы найти эту информацию – я просто подумал, что Python, возможно, уже разоблачил эти данные.

Изменить: Вот как я пытаюсь использовать это. У меня есть два разных приложения Django, которым необходимо записывать ошибки в файл. Допустим, что они называются «AppOne» и «AppTwo». У меня также есть место, где я хотел бы /home/hare/app_logs эти файлы: « /home/hare/app_logs ». В каждом приложении в любой заданной точке я хотел бы иметь возможность импортировать мой модуль журнала и вызвать функцию журнала, которая записывает строку журнала в файл. Однако то, что я хотел бы сделать, это создать каталог под app_logs который является именем текущего приложения («AppOne» или «AppTwo»), чтобы файлы журнала каждого приложения попадали в их соответствующие каталоги протоколирования.

Чтобы сделать это, я подумал, что лучший способ для модуля журнала должен иметь доступ к какой-то глобальной переменной, которая обозначает имя текущего приложения, поскольку оно отвечает за знание местоположения родительского каталога ведения журнала и создание журнала регистрации приложения если он еще не существует.

  • Статический метод vs функции модуля в python
  • Node.toprettyxml () добавляет новые строки в DOCTYPE в Python
  • Как вы прослушиваете уведомления из iTunes на Mac (используя NSDistributedNotificationCenter)
  • распаковка массива аргументов в php
  • Ошибка OpenCV: функция не реализована
  • Что означает этот код: «print >> sys.stderr»
  • Python dbfpy и FoxPro
  • Selenium Chromedriver висит?
  • 9 Solutions collect form web for “Как я могу получить доступ к текущему исполняющему модулю или имени класса в Python?”

    Из комментария – не вопрос.

    «Мне просто интересно узнать, возможно ли то, что я пытаюсь сделать».

    Ответ на вопрос «возможно ли это» всегда «да». Всегда. Если ваш вопрос не связан с путешествием во времени, антигравитацией или вечным движением.

    Поскольку ответ всегда «да», ваш вопрос плохо сформирован. Реальный вопрос: «Каков хороший способ узнать, как мой модуль регистрации знает имя клиента?» или что-то типа того.

    Ответ: «Примите его как параметр». Не возитесь с осмотром или поиском таинственных глобалов или других трюков.

    Просто следуйте шаблону проектирования logging.getLogger () и используйте явные имена журналов. Общей идиомой является следующее

     logger= logging.getLogger( __name__ ) 

    Это отлично подходит для всех имен журналов.

    Это должно работать для ссылки на текущий модуль:

     import sys sys.modules[__name__] 

    «Текущий исполняемый модуль», очевидно, является foo, так как это то, что содержит текущую функцию. Я думаю, что лучшее описание того, что вы хотите, это модуль непосредственного вызывающего устройства foo (который может быть foo, если вы вызываете af () от функции в foo, вызванной функцией в баре. Как далеко вы хотите подняться, зависит от того, для чего вы этого хотите.

    В любом случае, предполагая, что вы хотите немедленного вызова, вы можете получить это, подняв стек вызовов. Это можно сделать, вызвав sys._getframe , с подходящим количеством уровней для ходьбы.

     def f(): caller = sys._getframe(1) # Obtain calling frame print "Called from module", caller.f_globals['__name__'] 

    [Правка] : На самом деле использование модуля проверки, как было предложено выше, вероятно, является более чистым способом получения фрейма стека. Эквивалентный код:

     def f(): caller = inspect.currentframe().f_back print "Called from module", caller.f_globals['__name__'] 

    (sys._getframe документируется как для внутреннего использования – модуль проверки является более надежным API)

    Я думаю, что вы хотите использовать модуль проверки , для проверки стека времени выполнения python. Ознакомьтесь с этим уроком . Я думаю, что это почти точный пример того, что вы хотите сделать.

    __file__ – это путь текущего модуля, вызываемый вызовом.

    Я не думаю, что это возможно, так как это выходит за рамки foo . foo будет знать только о своей внутренней области, поскольку он может быть вызван множеством других модулей и приложений.

    Использование только __file__ дает вам относительный путь для основного модуля и абсолютный путь для импортированных модулей. Помня об этом, мы можем получить файл модуля постоянно в любом случае с небольшой помощью от наших инструментов os.path .

    Для имени файла используйте только __file__.split(os.path.sep)[-1] .

    Для полного пути используйте os.path.abspath(__file__) .

    Демо-версия:

     /tmp $ cat f.py from pprint import pprint import os import sys pprint({ 'sys.modules[__name__]': sys.modules[__name__], '__file__': __file__, '__file__.split(os.path.sep)[-1]': __file__.split(os.path.sep)[-1], 'os.path.abspath(__file__)': os.path.abspath(__file__), }) /tmp $ cat i.py import f 

    Результаты:

     ## on *Nix ## /tmp $ python3 f.py {'sys.modules[__name__]': <module '__main__' from 'f.py'>, '__file__': 'f.py', '__file__.split(os.path.sep)[-1]': 'f.py', 'os.path.abspath(__file__)': '/tmp/f.py'} /tmp $ python3 i.py {'sys.modules[__name__]': <module 'f' from '/tmp/f.pyc'>, '__file__': '/tmp/f.pyc', '__file__.split(os.path.sep)[-1]': 'f.pyc', 'os.path.abspath(__file__)': '/tmp/f.pyc'} ## on Windows ## PS C:\tmp> python3.exe f.py {'sys.modules[__name__]': <module '__main__' from 'f.py'>, '__file__': 'f.py', '__file__.split(os.path.sep)[-1]': 'f.py', 'os.path.abspath(__file__)': 'C:\\tools\\cygwin\\tmp\\f.py'} PS C:\tmp> python3.exe i.py {'sys.modules[__name__]': <module 'f' from 'C:\\tools\\cygwin\\tmp\\f.py'>, '__file__': 'C:\\tools\\cygwin\\tmp\\f.py', '__file__.split(os.path.sep)[-1]': 'f.py', 'os.path.abspath(__file__)': 'C:\\tools\\cygwin\\tmp\\f.py'} 

    Если вы хотите удалить «.py» с конца, вы можете сделать это легко. (Но не забывайте, что вместо этого вы можете запустить «.pyc»).

    Прошло некоторое время с тех пор, как я сделал python, но я считаю, что вы можете получить доступ к глобальным и локальным пользователям вызывающего абонента через его трассировку .

    Чтобы получить ссылку на модуль «__main__», когда в другом:

     import sys sys.modules['__main__'] 

    Чтобы затем получить путь к файлу модуля, который включает его имя:

     sys.modules['__main__'].__file__ 

    Если в модуле «__main__» просто используйте: __file__

    Чтобы получить только имя файла из пути к файлу:

     import os os.path.basename(file_path) 

    Чтобы отделить имя файла от его расширения:

     file_name.split(".")[0] 

    Чтобы получить имя экземпляра класса:

     instance.__class__.__name__ 

    Чтобы получить имя класса:

     class.__name__ 
    Interesting Posts
    Python - лучший язык программирования в мире.