Развертывание приложения Python с общим пакетом

Я думаю, как организовать развернутое приложение python, которое будет иметь

  1. Исполняемый скрипт, расположенный в /usr/bin/, который предоставляет интерфейс командной строки для функций, реализованных в
  2. Библиотека, установленная везде, где находится текущий каталог site-packages.

Теперь, в настоящее время, у меня есть следующая структура каталогов в моих источниках:

foo.py
foo/
  __init__.py
  ...

что, я думаю, не лучший способ сделать что-то. Во время разработки все работает так, как ожидалось, однако при развертывании код «из foo import FooObject» в foo.py, по-видимому, пытается импортировать сам foo.py, что не является тем поведением, которое я ищу.

Итак, вопрос в том, какова стандартная практика организации подобных ситуаций? Одна из вещей, о которых я мог подумать, это при установке переименовать foo.py просто в foo, что не позволит ему импортировать себя, но это кажется довольно неудобным...

Другая часть проблемы, я полагаю, заключается в том, что это проблема именования. Возможно, вызвать исполняемый скрипт foo-bin.py?


person Dimitri Tcaciuc    schedule 30.11.2008    source источник
comment
Разве это не то же самое, что... stackoverflow.com/questions/17893/   -  person dbr    schedule 30.11.2008


Ответы (4)


Эта статья довольно хороша и показывает, как это сделать. Второй пункт из списка Do отвечает на ваш вопрос.

бессовестная копипаста:

Структура файловой системы проекта Python

автор Дж. П. Кальдероне

Выполнить:

  • назовите каталог чем-то, что связано с вашим проектом. Например, если ваш проект называется «Twisted», назовите каталог верхнего уровня для его исходных файлов Twisted. Когда вы делаете выпуски, вы должны включать суффикс номера версии: Twisted-2.5.
  • создайте каталог Twisted/bin и поместите туда свои исполняемые файлы, если они у вас есть. Не давайте им расширение .py, даже если это исходные файлы Python. Не помещайте в них никакого кода, кроме импорта и вызова основной функции, определенной где-то еще в ваших проектах.
  • Если ваш проект можно представить в виде одного исходного файла Python, поместите его в каталог и назовите его как-нибудь, связанный с вашим проектом. Например, Twisted/twisted.py. Если вам нужно несколько исходных файлов, вместо этого создайте пакет (Twisted/twisted/, с пустым Twisted/twisted/__init__.py) и поместите в него свои исходные файлы. Например, Twisted/twisted/internet.py.
  • поместите свои модульные тесты в подпакет вашего пакета (обратите внимание - это означает, что указанный выше вариант с одним исходным файлом Python был уловкой - вам всегда нужен хотя бы один другой файл для ваших модульных тестов). Например, Twisted/twisted/test/. Конечно, сделать пакет с Twisted/twisted/test/__init__.py. Поместите тесты в файлы типа Twisted/twisted/test/test_internet.py.
  • добавьте Twisted/README и Twisted/setup.py, чтобы объяснить и установить свое программное обеспечение, соответственно, если вы чувствуете себя хорошо.

Не делайте этого.

  • поместите исходный код в каталог с именем src или lib. Это затрудняет запуск без установки.
  • поместите свои тесты за пределы вашего пакета Python. Это затрудняет запуск тестов для установленной версии.
  • создайте пакет, который имеет только __init__.py, а затем поместите весь свой код в __init__.py. Просто сделайте модуль вместо пакета, это проще.
  • попробуйте придумать волшебные хаки, чтобы Python мог импортировать ваш модуль или пакет, не заставляя пользователя добавлять каталог, содержащий его, в свой путь импорта (через PYTHONPATH или какой-либо другой механизм). Вы не сможете правильно обрабатывать все случаи, и пользователи будут злиться на вас, когда ваше программное обеспечение не работает в их среде.
person nosklo    schedule 02.12.2008
comment
Это хороший материал, и я буду его использовать, но я также хотел бы работать в Windows. Удаление расширения «.py» из файлов Python здесь кажется менее подходящим. Я что-то пропустил? Будет ли ваш процесс установки возвращать их обратно, заворачивать их или что-то в этом роде? - person Jonathan Hartley; 19.07.2009

Distutils поддерживает установку модулей, пакетов и скриптов. Если вы создаете distutils setup.py, который ссылается на foo как на пакет, а foo.py как на скрипт, то foo.py должен быть установлен в /usr/local/bin или любой другой соответствующий путь установки скрипта в целевой ОС, а пакет foo должен быть установлен в каталог site_packages .

person Matt Campbell    schedule 30.11.2008

Вы должны называть исполняемый файл просто foo, а не foo.py, тогда попытки импорта foo не будут его использовать.

Что касается правильного наименования: на это трудно ответить абстрактно; нам нужно знать, что именно он делает. Например, если он настраивает и контролирует, может быть уместным назвать его -config или ctl. Если это API-интерфейс оболочки для библиотеки, он должен иметь то же имя, что и библиотека.

person Martin v. Löwis    schedule 30.11.2008
comment
Каталог называется foo, так что это явно не сработает. Следующей лучшей вещью является bin/foo, но тогда вам придется возиться с sys.path, чтобы найти каталог вашего пакета. - person Rhamphoryncus; 29.05.2009

Ваш модуль CLI — это одно, пакет, который его поддерживает, — это другое. Не путайте названия модуля foo (в файле foo.py) и пакета foo (в каталоге foo с файлом __init__.py).

У вас есть две вещи с именем foo: модуль и пакет. Что еще вы хотите назвать foo? Класс? Функция? Переменная?

Выберите отличительное имя для модуля foo или пакета foo. foolib, например, — популярное имя пакета.

person S.Lott    schedule 30.11.2008