Какова наилучшая структура проекта для приложения на Python?[закрыто]
-
08-07-2019 - |
Вопрос
Представьте, что вы хотите разработать нетривиальное настольное (не веб-) приложение для конечного пользователя на Python.Каков наилучший способ структурировать иерархию папок проекта?
Желательными функциями являются простота обслуживания, удобство работы с IDE, пригодность для ветвления / объединения систем управления версиями и простота создания установочных пакетов.
В частности:
- Куда вы помещаете источник?
- Куда вы помещаете сценарии запуска приложений?
- Куда вы помещаете cruft IDE-проекта?
- Где вы проводите модульные / приемочные тесты?
- Куда вы помещаете данные, отличные от Python, такие как конфигурационные файлы?
- Куда вы помещаете исходные тексты, отличные от Python, такие как C ++, для модулей двоичного расширения pyd / so?
Решение
Это не так уж и важно.Все, что делает вас счастливыми, сработает.Существует не так уж много глупых правил, потому что проекты на Python могут быть простыми.
/scripts
или/bin
для такого рода интерфейса командной строки/tests
для ваших тестов/lib
для ваших библиотек на языке Си/doc
для большинства документов/apidoc
для документов API, сгенерированных Epydoc.
И каталог верхнего уровня может содержать файлы README, Config и еще много чего.
Трудный выбор заключается в том, использовать или не использовать /src
дерево.В Python нет различия между /src
, /lib
, и /bin
как у Java или C.
Начиная с высшего уровня /src
каталог рассматривается некоторыми как бессмысленный, ваш каталог верхнего уровня может быть архитектурой верхнего уровня вашего приложения.
/foo
/bar
/baz
Я рекомендую поместить все это в каталог "название моего продукта".Итак, если вы пишете приложение с именем quux
, каталог , содержащий все это , называется /quux
.
Другой проект PYTHONPATH
, тогда, может включать в себя /path/to/quux/foo
для повторного использования QUUX.foo
модуль.
В моем случае, поскольку я использую Komodo Edit, мой IDE cuft представляет собой один файл .KPF.Я действительно вывел это на верхний уровень /quux
каталог, и не добавляйте его в SVN.
Другие советы
Согласно структуре файловой системы Жана-Пола Кальдероне Проект Python :
Project/
|-- bin/
| |-- project
|
|-- project/
| |-- test/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- __init__.py
| |-- main.py
|
|-- setup.py
|-- README
Это запись в блоге Жан-Поля Кальдероне обычно задается в качестве ответа в #python на Freenode.
Структура файловой системы проекта на Python
Делай:
- назовите каталог чем-нибудь, связанным с вашим проектом.Например, если ваш проект называется "Twisted", назовите каталог верхнего уровня для его исходных файлов
Twisted
.Когда вы делаете релизы, вы должны указывать суффикс номера версии:Twisted-2.5
.- создайте каталог
Twisted/bin
и поместите туда свои исполняемые файлы, если они у вас есть.Не давайте им повода для беспокойства..py
расширение, даже если это исходные файлы Python.Не помещайте в них никакого кода, кроме импорта и вызова основной функции, определенной где-то еще в ваших проектах.(Небольшая морщинка:поскольку в Windows интерпретатор выбирается по расширению файла, ваши пользователи Windows на самом деле хотят расширение .py.Итак, когда вы создаете пакет для Windows, вы можете захотеть добавить его.К сожалению, я не знаю простого способа автоматизации этого процесса с помощью distutils.Учитывая, что в POSIX расширение .py - это всего лишь ошибка, тогда как в Windows отсутствие является реальной ошибкой, если в вашей пользовательской базе есть пользователи Windows, вы можете захотеть использовать расширение .py везде.)- Если ваш проект можно выразить в виде одного исходного файла 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, либо каким-либо другим механизмом).Ты будешь нет правильно обрабатывайте все обращения, и пользователи будут сердиться на вас, когда ваше программное обеспечение не будет работать в их среде.
Проверьте Откройте правильный источник для проекта на Python.
Позвольте мне привести выдержку из макет проекта часть этой замечательной статьи:
При настройке проекта важно правильно настроить макет (или структуру каталогов).Разумный макет означает, что потенциальным участникам не нужно вечно искать фрагмент кода;расположение файлов интуитивно понятно.Поскольку мы имеем дело с существующим проектом, это означает, что вам, вероятно, потребуется кое-что переместить.
Давайте начнем с самого верха.В большинстве проектов есть несколько файлов верхнего уровня (например, setup.py, README.md, requirements.txt и т.д.).Таким образом, существует три каталога, которые должны быть у каждого проекта:
- Каталог docs, содержащий проектную документацию
- Каталог, названный именем проекта, в котором хранится фактический пакет Python
- Тестовый каталог в одном из двух мест
- В каталоге пакетов, содержащем тестовый код и ресурсы
- Как отдельный каталог верхнего уровня Чтобы лучше понять, как должны быть организованы ваши файлы, вот упрощенный снимок макета для одного из моих проектов, sandman:
$ pwd
~/code/sandman
$ tree
.
|- LICENSE
|- README.md
|- TODO.md
|- docs
| |-- conf.py
| |-- generated
| |-- index.rst
| |-- installation.rst
| |-- modules.rst
| |-- quickstart.rst
| |-- sandman.rst
|- requirements.txt
|- sandman
| |-- __init__.py
| |-- exception.py
| |-- model.py
| |-- sandman.py
| |-- test
| |-- models.py
| |-- test_sandman.py
|- setup.py
Как вы можете видеть, есть несколько файлов верхнего уровня, каталог docs (сгенерированный - это пустой каталог, куда sphinx поместит сгенерированную документацию), каталог sandman и тестовый каталог в sandman.
" Python Packaging Authority " имеет образец проекта:
https://github.com/pypa/sampleproject
Это пример проекта, который существует в качестве пособия к Руководству пользователя Python по созданию пакетов по проектам упаковки и распространения.
Попробуйте запустить проект с помощью python_boilerplate питон_боилерплата шаблон.Он в значительной степени соответствует лучшим практикам (например, те, кто здесь), но лучше подходит на случай, если в какой-то момент вы обнаружите, что готовы разделить свой проект более чем на одно яйцо (и поверьте мне, с любыми проектами, кроме самых простых, вы это сделаете.Одна из распространенных ситуаций заключается в том, что вам приходится использовать локально измененную версию чужой библиотеки).
Куда вы помещаете источник?
- Для прилично крупных проектов имеет смысл разделить исходный код на несколько частей.Каждое яйцо будет отображаться как отдельный setuptools-макет в разделе
PROJECT_ROOT/src/<egg_name>
.
- Для прилично крупных проектов имеет смысл разделить исходный код на несколько частей.Каждое яйцо будет отображаться как отдельный setuptools-макет в разделе
Куда вы помещаете сценарии запуска приложений?
- Идеальным вариантом является регистрация сценария запуска приложения в качестве
entry_point
в одном из яиц.
- Идеальным вариантом является регистрация сценария запуска приложения в качестве
Куда вы помещаете cruft IDE-проекта?
- Зависит от среды разработки.Многие из них хранят свои вещи в
PROJECT_ROOT/.<something>
в корневом каталоге проекта, и это нормально.
- Зависит от среды разработки.Многие из них хранят свои вещи в
Где вы проводите модульные / приемочные тесты?
- Каждое яйцо имеет отдельный набор тестов, хранящихся в
PROJECT_ROOT/src/<egg_name>/tests
справочник.Лично я предпочитаю использоватьpy.test
чтобы управлять ими.
- Каждое яйцо имеет отдельный набор тестов, хранящихся в
Куда вы помещаете данные, отличные от Python, такие как конфигурационные файлы?
- Это зависит от обстоятельств.Могут существовать различные типы данных, отличных от Python.
- "Ресурсы", т. е.данные, которые должны быть упакованы в яйцо.Эти данные отправляются в соответствующий каталог egg, где-то в пространстве имен package.Он может быть использован через
pkg_resources
посылка. - "Конфигурационные файлы", т. е.файлы, отличные от Python, которые следует рассматривать как внешние по отношению к исходным файлам проекта, но должны быть инициализированы некоторыми значениями при запуске приложения.Во время разработки я предпочитаю хранить такие файлы в
PROJECT_ROOT/config
.Для развертывания могут быть различные варианты.В Windows можно использовать%APP_DATA%/<app-name>/config
, в Linux,/etc/<app-name>
или/opt/<app-name>/config
. - Сгенерированные файлы, т. е.файлы, которые могут быть созданы или изменены приложением во время выполнения.Я бы предпочел оставить их в
PROJECT_ROOT/var
во время разработки и в рамках/var
во время развертывания Linux.
- "Ресурсы", т. е.данные, которые должны быть упакованы в яйцо.Эти данные отправляются в соответствующий каталог egg, где-то в пространстве имен package.Он может быть использован через
- Это зависит от обстоятельств.Могут существовать различные типы данных, отличных от Python.
- Куда вы помещаете исходные тексты, отличные от Python, такие как C ++, для модулей двоичного расширения pyd / so?
- В
PROJECT_ROOT/src/<egg_name>/native
- В
Документация, как правило, включает в себя PROJECT_ROOT/doc
или PROJECT_ROOT/src/<egg_name>/doc
(это зависит от того, относите ли вы некоторые яйца к отдельным крупным проектам).Некоторые дополнительные настройки будут содержаться в таких файлах, как PROJECT_ROOT/buildout.cfg
и PROJECT_ROOT/setup.cfg
.
По моему опыту, это просто вопрос итерации. Размещайте свои данные и код там, где, по вашему мнению, они идут. Скорее всего, вы все равно будете неправы. Но как только вы получите лучшее представление о том, как все будет складываться, вы будете в гораздо лучшем положении, чтобы делать подобные предположения.
Что касается источников расширений, у нас есть каталог Code в транке, который содержит каталог для python и каталог для различных других языков. Лично я больше склонен в следующий раз попытаться поместить любой код расширения в свой собственный репозиторий.
Сказав это, я возвращаюсь к своей исходной точке: не делайте из этого слишком большой сделки. Поместите это где-нибудь, что, кажется, работает для Вас. Если вы найдете что-то, что не работает, это можно (и нужно) изменить.
Данные, не относящиеся к Python, лучше всего объединять в своих модулях Python с помощью поддержки package_data
в setuptools . Я настоятельно рекомендую использовать пакеты пространств имен для создания общих пространств имен, которые могут использовать несколько проектов - во многом как соглашение Java о размещении пакетов в com.yourcompany.yourproject
(и возможность иметь общее пространство имен com.yourcompany.utils
).
Повторное ветвление и слияние, если вы используете достаточно хорошую систему контроля версий, она будет обрабатывать слияния даже через переименования; Bazaar особенно хорош в этом.
Вопреки некоторым другим ответам здесь, я +1 за наличие каталога верхнего уровня src
(вместе с каталогами doc
и test
). Конкретные соглашения для деревьев каталогов документации будут варьироваться в зависимости от того, что вы используете; Sphinx , например, имеет свои собственные соглашения, которые поддерживает его инструмент быстрого запуска.
Пожалуйста, используйте средства настройки и pkg_resources; это значительно упрощает использование другими проектами определенных версий вашего кода (и одновременную установку нескольких версий с разными файлами, не относящимися к коду, если вы используете <=>).