Какова наилучшая структура проекта для приложения на Python?[закрыто]

StackOverflow https://stackoverflow.com/questions/193161

Вопрос

Представьте, что вы хотите разработать нетривиальное настольное (не веб-) приложение для конечного пользователя на Python.Каков наилучший способ структурировать иерархию папок проекта?

Желательными функциями являются простота обслуживания, удобство работы с IDE, пригодность для ветвления / объединения систем управления версиями и простота создания установочных пакетов.

В частности:

  1. Куда вы помещаете источник?
  2. Куда вы помещаете сценарии запуска приложений?
  3. Куда вы помещаете cruft IDE-проекта?
  4. Где вы проводите модульные / приемочные тесты?
  5. Куда вы помещаете данные, отличные от Python, такие как конфигурационные файлы?
  6. Куда вы помещаете исходные тексты, отличные от 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>.
  • Куда вы помещаете сценарии запуска приложений?

    • Идеальным вариантом является регистрация сценария запуска приложения в качестве 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.
  • Куда вы помещаете исходные тексты, отличные от 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; это значительно упрощает использование другими проектами определенных версий вашего кода (и одновременную установку нескольких версий с разными файлами, не относящимися к коду, если вы используете <=>).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top