2011-03-03 2 views
24

Я искал, и это кажется простым вопросом без простого ответа.Как получить текущий текущий путь/имя пула

У меня есть файл 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 без необходимости фактически записать фактическое значение каждого сценария.

Нужно ли мне пройти через inspect, чтобы получить требуемое значение?

Спасибо.

EDIT: Как уже говорилось, есть ответы (я искал), но не простые ответы. Используйте либо inspect, либо используйте traceback, либо манипулируйте __file__ и __package__ и выполните подстроку, чтобы получить ответ. Но ничего такого простого, как если бы у меня был класс в модуле, я мог бы просто использовать myClass.__module__, и я бы получил ответ, который я хочу. Использование __name__ (к сожалению) бесполезно, так как это всегда __main__.

Кроме того, это в python 2.6, и я не могу использовать другие версии.

+0

Помогает ли вам эта нить? http://stackoverflow.com/questions/247770/retrieving-python-module-path – birryree

+0

Существует несколько кандидатов для дубликатов: http://stackoverflow.com/questions/4288905/how-do-you-show-the-path -of-the-current-running-python-module, http://stackoverflow.com/questions/1450478/how-do-get-the-name-of-a-running-python-script –

+0

Я думаю, что это не является дубликатом. В предыдущих комментариях упомянутые проблемы направлены на то, чтобы получить путь к исполняемому файлу в файловой системе, тогда как ПО хочет получить текущий python [package] (http://docs.python.org/ py3k/tutorial/modules.html # packages) + [module] (http://docs.python.org/py3k/tutorial/modules.html) – gecco

ответ

24

Это работает для меня:

__loader__.fullname 

Кроме того, если я питона -m b.c из \ я получаю 'b.c', как и ожидалось.

Не совсем уверен, что такое атрибут __loader__, поэтому дайте мне знать, если это не хорошо.

редактировать: Это происходит из PEP 302: http://www.python.org/dev/peps/pep-0302/

Интересные фрагменты из ссылки:

load_module() метод имеет несколько функций, которые он должен выполнить перед тем он работает любой код:

...

  • Он должен добавить к модулю атрибут __loader__, установленный на объект-загрузчик . Это в основном для самоанализа, но может быть использовано для специальных импортеров, например, для получения данных с импортером.

Таким образом, похоже, что он должен работать нормально во всех случаях.

+0

Для меня это должно быть '__loader __. Name'. См. Doc на странице https://docs.python.org/3/library/importlib.html#importlib.abc.FileLoader – ronen

5

При работе с -m, sys.path[0] содержит полный путь к модулю. Вы можете использовать это для создания имени.

источник: http://docs.python.org/using/cmdline.html#command-line

Другим вариантом может быть __package__ построен в переменной, которая доступна в модулях.

+0

Спасибо. Я редактировал свой вопрос, чтобы указать, что я знаю, как манипулировать, чтобы получить ответ, я надеялся на более простой способ, не проверяя его сам. – Danosaure

+0

Вы имели в виду 'sys.argv [0]'. – CristiFati

9

Я думаю, что вы действительно ищете специальную переменную __name__. Из Python documentation:

Внутри модуля, имя модуля (в виде строки) доступна в качестве значения глобальной переменной __name__.

Если вы запустите файл напрямую, это имя будет __main__. Однако, если вы находитесь в модуле (как в случае, когда вы используете флаг -m или любой другой импорт), это будет полное имя модуля.

+3

\ __ name _ \ _ будет «основным», если он вызывается с флагом «-m». – Danosaure

1

Единственный способ - манипулировать путями с помощью os.getcwd(), os.path, файла и еще чего, как вы упомянули.

На самом деле, это может быть хороший патч реализовать для optparse/argparse (который в настоящее время заменить «% прог» в строке с использованием os.path.basename (sys.argv [0]) - вы являются используя optparse, right? -), то есть другую специальную строку, такую ​​как% module.

+0

Я все еще фактически использую пакет компании, который все еще использует getopt. Модуль был создан еще в 2006-2007 годах? – Danosaure

0

Не могу понять, почему существует такое ограничение, как «python -m a.b.c». Конечно, фактический модуль может находиться внутри какого-либо zip-файла или что-то еще, но я бы упростил весь подход с помощью сценария-оболочки, который гарантирует, что выполнение происходит в правильном контексте, с правильным экземпляром python.

Обертка может содержать всего:

import sys 
__import__(sys.argv[1]) 

Затем вы можете использовать свой любимый метод, чтобы получить имя модуля для использования.

возврат к первоначальному требованию. Если я правильно понял, идея заключается в том, что кто-то запускает файл python в какой-то под-каталог, чтобы узнать из сообщения об использовании, что он действительно является модулем some.mega.package.

Я думаю, нет надежного, общего способа определить, хотите ли вы запускать c, bc или abc-модуль, без какого-либо анализа файловой системы с определенными эвристиками (скажем, найти все __init__.py во внешних каталогах до очков больше нет __init__.py), и даже с анализом его не 100%.

+0

Я изменил политику своей компании, чтобы прекратить ставить скрипты в/usr/local/bin, которые были сложны для очистки или было сложно найти, кто из какого проекта. Поэтому мы теперь держим скрипты утилиты в своем собственном пакете. – Danosaure

-1

вы должны жёстко a.b.c в вашей помощи, если вы распространяете пакет как таковой, то это способ вызвать его, независимо от того, где a находится в файловой системе, до тех пор, как это на PYTHONPATH он будет импортироваться.

+0

Это не соответствует моей потребности. Проблема жесткого кодирования всегда, если я изменяю имя моего файла, мне нужно запомнить текст справки. – Danosaure

+0

Если вы измените имя файла, все импорт будет разорван, поэтому текст справки будет меньше ваших проблем. –

+0

Сценарий является точкой входа, он не импортируется другими модулями, поэтому эта проблема не применяется. – Danosaure

-1

Количество опций для получения пути/имени текущего модуля.

Сначала ознакомьтесь с использованием __file__ в Python, Click here to see the usage.

Он содержит имя загруженного в настоящее время модуля .

Проверка/Попробуйте следующий код, он будет работать как на python2 & Python3.

# 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 

Итак, мы получили название имени текущего модуля и его абсолютного пути.

Смежные вопросы