Какова лучшая структура проекта для приложения Python? [закрытый]
представьте, что вы хотите разработать нетривиальное приложение для рабочего стола конечного пользователя (не веб-приложение) в Python. Как лучше всего структурировать иерархию папок проекта?
желательные характеристики легкость обслуживания, IDE-дружелюбие, пригодность для разветвления/слияния системы управления версиями, и легкое поколение пакетов установки.
в частности:
- куда вы кладете источник?
- куда вы помещаете запуск приложения сценарии?
- куда вы помещаете проект IDE cruft?
- где вы ставите модуль / приемочные испытания?
- куда вы помещаете данные, отличные от Python, такие как файлы конфигурации?
- где вы помещаете не Python источники, такие как C++ для pyd/so бинарных модулей расширения?
8 ответов:
не имеет значения. Все, что делает вас счастливыми, будет работать. Существует не так много глупых правил, потому что проекты Python могут быть простыми.
/scriptsили/binдля такого рода интерфейса командной строки вещи/testsдля тестов/libдля ваших библиотек языка C/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-это один .Файл КПФ. Я на самом деле положил это на верхнем уровне
/quuxкаталог, и опустить добавление его в SVN.
по словам Жан-Поля Кальдерона структура файловой системы проекта Python:
Project/ |-- bin/ | |-- project | |-- project/ | |-- test/ | | |-- __init__.py | | |-- test_main.py | | | |-- __init__.py | |-- main.py | |-- setup.py |-- README
этой сообщение в блоге Жан-Поля Кальдерона обычно дается как ответ в #python на Freenode.
структура файловой системы проекта Python
Do:
- назовите каталог, связанный с вашим проектом. Например, если ваш проект называется "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, требования.txt, etc). Есть тогда три каталога, которые каждый проект должен иметь:
- каталог документов, содержащий проектную документацию
- каталог с именем проекта, в котором хранится фактический пакет Python
- тестовый каталог в одном из двух мест
- в каталоге пакетов, содержащем тестовый код и ресурсы
- как автономный каталог верхнего уровня Чтобы лучше понять, как ваши файлы должны быть организованы, вот упрощенный снимок макета для одного из моих проектов, Песочный человек:
$ 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 (генерируется пустой каталог, где Сфинкс будет помещать сгенерированный документация), каталог sandman и тестовый каталог под sandman.
"Python Packaging Authority" имеет sampleproject:
https://github.com/pypa/sampleproject
Это пример проекта, который существует в качестве помощи в руководстве пользователя Python Packaging по упаковке и распространению проектов.
попробуйте запустить проект с помощью python_boilerplate шаблон. Он в значительной степени следует лучшим практикам (например,здесь), но лучше подходит в случае, если вы обнаружите, что готовы разделить свой проект на более чем одно яйцо в какой-то момент (и поверьте мне, с чем угодно, кроме самых простых проектов, вы будете. Одна из распространенных ситуаций заключается в том, что вам нужно использовать локально измененную версию чужой библиотека.)
куда вы кладете источник?
- для прилично больших проектов имеет смысл разбить источник на несколько яиц. Каждое яйцо будет идти как отдельный setuptools-макет под
PROJECT_ROOT/src/<egg_name>.куда вы помещаете сценарии запуска приложений?
- идеальный вариант-иметь сценарий запуска приложения, зарегистрированный как
entry_pointin одно из яиц.куда вы помещаете проект IDE cruft?
- зависит от IDE. Многие из них хранят свои вещи в
PROJECT_ROOT/.<something>в корне проекта, и это нормально.где вы ставите модуль / приемочные испытания?
- каждое яйцо имеет отдельный набор тестов, хранящихся в его . Я лично предпочитаю использовать
py.testзапустить их.куда вы помещаете данные, отличные от Python, такие как файлы конфигурации?
- это зависит. Существуют различные типы данных, отличных от Python.
- "ресурсы", т. е. данные, которые должны быть упакованы в яйце. Эти данные поступают в соответствующий каталог egg, где-то в пространстве имен пакета. Его можно использовать через
pkg_resourcesпакет.- "Config-files", т. е. не 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.
по моему опыту, это просто вопрос итерации. Поместите свои данные и код, где вы думаете, что они идут. Скорее всего, вы все равно ошибетесь. Но как только вы получите лучшее представление о том, как именно все будет складываться, вы окажетесь в гораздо лучшем положении, чтобы сделать такие предположения.
Что касается источников расширения, у нас есть каталог кода под транком, который содержит каталог для python и каталог для различных других языков. Лично я больше склоняюсь к попробовать в следующий раз поместите любой код расширения в свой собственный репозиторий.
с учетом сказанного, я возвращаюсь к своей первоначальной точке: не делайте из этого слишком большого дела. Положите его где-нибудь, что, кажется, работает для вас. Если вы найдете что-то, что не работает, это может (и должно) быть изменено.
данные, отличные от python, лучше всего упаковывать внутри ваших модулей Python, используя
package_dataподдержка в setuptools. Одна вещь, которую я настоятельно рекомендую использовать пакеты пространств имен для создания общих пространств имен, которые могут использовать несколько проектов-так же, как соглашение Java о размещении пакетов вcom.yourcompany.yourproject(и возможность иметь общийcom.yourcompany.utilsпространство имен).повторное ветвление и слияние, если вы используете достаточно хорошую систему управления версиями, она будет обрабатывать слияния даже через переименовывает; базар особенно хорош в этом.
в отличие от некоторых других ответов здесь, я +1 на наличие
srcкаталог верхнего уровня (сdocиtestкаталоги вместе). Конкретные соглашения для деревьев каталогов документации будут отличаться в зависимости от того, что вы используете;Сфинкс, например, имеет свои собственные соглашения, которые поддерживает его инструмент быстрого запуска.пожалуйста, пожалуйста, используйте setuptools и pkg_resources; это делает для других проектов гораздо проще полагаться на определенные версии вашего кода (и для одновременной установки нескольких версий с разными некодовыми файлами, если вы используете
package_data).
Comments