Как получить текущий текущий путь/имя модуля
Я искал, и это, кажется, простой вопрос без простого ответа.
У меня есть файл a/b/c.py
, который будет вызываться с помощью python -m a.b.c
. Я хотел бы получить значение a.b.c
на уровне модуля.
USAGE = u'''\
Usage:
python -m %s -h
''' % (what_do_i_put_here,)
Поэтому, когда я получаю параметр -h
, я показываю USAGE
без необходимости фактически записывать фактическое значение в каждом script.
Нужно ли мне пройти через inspect
, чтобы получить желаемое значение?
Спасибо.
EDIT: Как сказано, есть ответы (я искал), но не простые ответы. Либо используйте inspect
, используйте traceback
, либо манипулируйте __file__
и __package__
и выполните некоторую подстроку, чтобы получить ответ. Но ничего такого простого, как если бы у меня был класс в модуле, я мог бы просто использовать myClass.__module__
, и я бы получил ответ, который я хочу. Использование __name__
(к сожалению) бесполезно, поскольку оно всегда __main__
.
Кроме того, это в python 2.6, и я не могу использовать другие версии.
Ответы
Ответ 1
Это работает для меня:
__loader__.fullname
Также, если я делаю python -m b.c из \I get 'b.c', как ожидалось.
Не совсем уверен, что такое атрибут __loader__, поэтому дайте мне знать, если это не хорошо.
edit. Он исходит из PEP 302: http://www.python.org/dev/peps/pep-0302/
Интересные фрагменты из ссылки:
Метод load_module() имеет несколько обязанностей, которые он должен выполнить перед выполнением любого кода:
...
- Он должен добавить к модулю атрибут __loader__, установленный на объект загрузчика. Это в основном для интроспекции, но может быть использовано для специальных импортеров, например, для сбора данных с импортером.
Итак, похоже, что он должен работать нормально во всех случаях.
Ответ 2
Я думаю, что вы действительно ищете специальную переменную __name__
. Из Документация Python:
Внутри модуля имя модуля (как строка) доступно как значение глобальной переменной __name__
.
Если вы запустите файл напрямую, это имя будет __main__
. Однако, если вы находитесь в модуле (как в случае, когда вы используете флаг -m или любой другой импорт), это будет полное имя модуля.
Ответ 3
При запуске с -m, sys.path[0]
содержит полный путь к модулю. Вы можете использовать это для создания имени.
источник: http://docs.python.org/using/cmdline.html#command-line
Другим вариантом может быть встроенная переменная __package__
, доступная в модулях.
Ответ 4
Единственный способ - манипулировать путями с os.getcwd(), os.path, файлом и тем, что вы упомянули.
На самом деле это может быть хороший патч для реализации optparse/argparse (который в настоящее время заменяет "% prog" в строке использования с os.path.basename(sys.argv [0]) - вы используете optparse, right? -), то есть другая специальная строка, например% module.
Ответ 5
Количество вариантов, чтобы получить путь/имя текущего модуля.
Сначала ознакомьтесь с использованием __file__ в Python, Нажмите здесь, чтобы увидеть использование.
Он содержит имя загруженного в данный момент модуля.
Проверьте/попробуйте следующий код, он будет работать как на Python2, так и на Python3.
& RAQUO; module_names.py
import os
print (__file__)
print (os.path.abspath(__file__))
print (os.path.realpath(__file__))
Вывод в MAC OS X:
MacBook-Pro-2:practice admin$ python module_names.py
module_names.py
/Users/admin/projects/Python/python-the-snake/practice/module_names.py
/Users/admin/projects/Python/python-the-snake/practice/module_names.py
Итак, здесь мы получили имя текущего имени модуля и его абсолютный путь.
Ответ 6
Не могу понять, почему существует такое ограничение, как "python -m a.b.c". Конечно, фактический модуль может находиться внутри какого-то zip файла или что-то еще, но я бы упростил весь подход с помощью обертки script, которая гарантирует, что выполнение происходит в правильном контексте с правильным экземпляром python.
Оболочка может содержать всего лишь:
import sys
__import__(sys.argv[1])
Затем вы можете использовать свой любимый метод, чтобы получить имя модуля для использования.
вернуться к первоначальному требованию. Если я правильно понял, идея заключается в том, что кто-то запускает файл python в какой-то под-каталог, чтобы узнать из сообщения об использовании, что он действительно является модулем some.mega.package.
Я думаю, нет надежного, общего способа определить, хотите ли вы запустить c, bc или abc-модуль, без какого-либо анализа файловой системы с определенными эвристиками (скажем, найти все __init__.py во внешних каталогах до тех пор, пока точки больше нет __init__.py), и даже при анализе его не 100%.
Ответ 7
Почему никто не упомянул .__module__
?
При выполнении self.__module__
вы получите путь к модулю.
Вы также можете сделать это вне класса:
Class A:
self.__module__ # gets module.filename
def get_module():
A.__module__ # also gets module.filename
Ответ 8
вам следует жестко указать a.b.c
в свою помощь, если вы распространёте пакет как таковой, чтобы способ его вызова вне зависимости от того, где a
находится в файловой системе, пока он на PYTHONPATH будет импортирован.