Выполнить установленный пакет Python как script?
Есть ли способ включить пакет в качестве script? Например:
[~]# easy_install /path/to/foo.egg
...
[~]# python -m foo --name World
Hello World
Я попытался создать файл __main__.py
внутри моего пакета, но он не выполняется (я использую Python 2.6). Возникает следующая ошибка:
foo is a package and cannot be directly executed
Структура моего пакета выглядит следующим образом:
foo/
setup.py
foo/
__init__.py
__main__.py
Запуск python -m foo.__main__ --name World
работает так, как ожидалось, но я предпочел бы прежний способ исполнения. Возможно ли это?
Ответы
Ответ 1
Это регрессия в Python 2.6. См. issue2571:
Возможность выполнять пакеты никогда не планировалась, так как ломает импорт различными путями. На самом деле это была ошибка в 2.5, что это было разрешено вообще, поэтому 2.6 не только снова отключил его, но также добавил тест, чтобы убедиться, что он отключен (2.4 правильно отклонил его с помощью ImportError, как это делает 2.6).
У вас есть несколько вариантов, вы можете либо всегда запускать его, указав main:
$ python -m module.__main__
Или вы можете написать оболочку script, которая обнаруживает версию python, а затем выполняет ее в другом стиле.
Или вы можете выполнить код в командной строке, который будет импортировать, а затем запустить модуль, а затем, возможно, поместить его в оболочку script:
$ python -c "import module; module.main()"
В моих собственных проектах с командной строкой у меня есть и оболочка script, которая ловит ошибки (python не устанавливается и т.д.), но оболочка script также выполняет код импорта и обнаруживает, были ли необходимые модули (с полезной ссылкой или установочным текстом).
Ответ 2
Я думаю, что это может быть ограничение Python 2.6. Я протестировал его, и выполнение пакета (либо в .
, либо установленном из яйца с easy_install) с опцией -m
работает отлично в 2.7, но не в 2.6. Например, в моей системе (Ubuntu) с тестовым пакетом с именем pkg_exec
в текущем каталоге и где __main__.py
просто печатает sys.argv
:
[email protected]:~/tmp/pkg_exec$ python2.6 -m pkg_exec
/usr/bin/python2.6: pkg_exec is a package and cannot be directly executed
[email protected]:~/tmp/pkg_exec$ python2.7 -m pkg_exec
['/home/xx/tmp/pkg_exec/pkg_exec/__main__.py']
Кроме того, согласно 2.7 docs:
Изменено в версии 2.7: укажите имя пакета для запуска подмодуля __main__
.
Ответ 3
пока пакет находится на пути python,
добавьте в конец script.
if __name__ == "__main__":
call_script()
$ python -m module_name
запустит модуль, например,
python -m random