Я начал работать с Python. Я добавил requirements.txt
и setup.py
в свой проект. Но я все еще не понимаю, зачем нужны оба файла. Я читал, что setup.py
это предназначено для распространяемых вещей и requirements.txt
предназначено для нераспространяемых вещей. Но я не уверен, что это правда.
Как эти два файла действительно предназначены для использования?
Ответы:
requirements.txt
Это поможет вам настроить среду разработки. Такие программы, как
pip
можно использовать для установки всех пакетов, перечисленных в файле, одним махом. После этого вы можете приступить к разработке своего скрипта на Python. Это особенно полезно, если вы планируете, чтобы другие участвовали в разработке или использовали виртуальные среды. Вот как вы его используете:setup.py
Это позволяет вам создавать пакеты, которые вы можете распространять. Этот сценарий предназначен для установки вашего пакета в системе конечного пользователя, а не для подготовки среды разработки, как это
pip install -r requirements.txt
делается. См. Этот ответ для получения дополнительных сведений о setup.py.Зависимости вашего проекта перечислены в обоих файлах.
источник
Короткий ответ: только
requirements.txt
для перечисления требований к пакету.setup.py
с другой стороны, это больше похоже на сценарий установки. Если вы не планируете устанавливать код Python, обычно вам понадобится толькоrequirements.txt
.Файл
setup.py
описывает, помимо зависимостей пакетов, набор файлов и модулей, которые должны быть упакованы (или скомпилированы, в случае собственных модулей (т.е. написанных на C)), и метаданные для добавления в списки пакетов python ( например, имя пакета, версия пакета, описание пакета, автор, ...).Поскольку в обоих файлах перечислены зависимости, это может привести к небольшому дублированию. Подробности читайте ниже.
requirements.txt
В этом файле перечислены требования к пакету Python. Это простой текстовый файл (необязательно с комментариями), в котором перечислены зависимости пакетов вашего проекта python (по одной в каждой строке). Он не описывает способ установки вашего пакета python. Обычно вы используете файл требований с расширением
pip install -r requirements.txt
.Имя текстового файла может быть произвольным, но часто
requirements.txt
по соглашению. Изучая репозитории исходного кода других пакетов Python, вы можете наткнуться на другие имена, такие какdev-dependencies.txt
илиdependencies-dev.txt
. Они служат той же цели,dependencies.txt
но обычно перечисляют дополнительные зависимости, представляющие интерес для разработчиков конкретного пакета, а именно для тестирования исходного кода (например, pytest, pylint и т. Д.) Перед выпуском. Пользователям пакета обычно не требуется весь набор зависимостей разработчика для запуска пакета.Если присутствует несколько
requirements-X.txt
вариантов, то обычно в одном будут перечислены зависимости времени выполнения, а в другом - зависимости времени сборки или тестирования. Некоторые проекты также каскадируют свои файлы требований, т.е. когда один файл требований включает другой файл ( пример ). Это может уменьшить количество повторений.setup.py
Это сценарий python, который использует
setuptools
модуль для определения пакета python (имя, включенные файлы, метаданные пакета и установка). Он также будетrequirements.txt
отображать зависимости пакета во время выполнения. Setuptools - это де-факто способ создания и установки пакетов python, но он имеет свои недостатки, которые со временем привели к разработке новых «менеджеров метапакетов», таких как pip. Примеры недостатков setuptools - это невозможность установить несколько версий одного и того же пакета и отсутствие команды удаления.Когда пользователь python делает
pip install ./pkgdir_my_module
(илиpip install my-module
), pip запускаетсяsetup.py
в данном каталоге (или модуле). Точно так же любой модуль, у которого есть,setup.py
можно установитьpip
, например, запустив егоpip install .
из той же папки.Мне действительно нужны оба?
Короткий ответ - нет, но приятно иметь и то, и другое. Они достигают разных целей, но оба могут использоваться для перечисления ваших зависимостей.
Есть один прием, который вы можете использовать, чтобы избежать дублирования списка зависимостей между
requirements.txt
иsetup.py
. Если вы уже написали полностью рабочийsetup.py
пакет для своего пакета, и ваши зависимости в основном внешние, вы можете подумать о простом пакетеrequirements.txt
только со следующим:Это
-e
специальнаяpip install
опция, которая устанавливает данный пакет в редактируемом режиме. Приpip -r requirements.txt
запуске этого файла pip установит ваши зависимости через список в./setup.py
. Редактируемый вариант поместит символическую ссылку в ваш установочный каталог (вместо яйца или заархивированной копии). Это позволяет разработчикам редактировать код на месте из репозитория без переустановки.Вы также можете воспользоваться тем, что называется «дополнительными средствами setuptools», если у вас есть оба файла в репозитории пакетов. Вы можете определить дополнительные пакеты в setup.py в настраиваемой категории и установить эти пакеты только из этой категории с помощью pip:
а затем в файле требований:
Это сохранит все ваши списки зависимостей внутри setup.py.
Примечание . Обычно pip и setup.py выполняются из песочницы, например, созданной с помощью программы
virtualenv
. Это позволит избежать установки пакетов python вне контекста среды разработки вашего проекта.источник
.
без него-e
внутриrequirements.txt
. Этот метод просто делегирует все требования,setup.py
и вам не нужно никого принудительно переводить в редактируемый режим. Пользователи все еще могут делать это,pip install -e .
если хотят.-e .
также использует setup.py для поиска зависимостей, но связывает текущую папку (на месте, с символической ссылкой) в папке установки pip, а не берет копию - вы-e
обычно будете использовать, только если вы разрабатываете пакет. С-e
, изменения в ваших файлах пакета python (* .py) вступят в силу немедленно в вашей среде pip, вместо того, чтобы принудительно переустанавливать пакет после каждого изменения.cd foo && pip install -r ./bar/requirements.txt
, он будет искать setup.py вfoo/bar
илиfoo
? Если второе, есть ли способ достичь первого?pip -r REQ
не заботится о каталоге, в котором находится REQ. Вы можете кормить его из ФИФО , даже если вы хотите:pip install -r <(echo "mylib1"; echo "mylib2";)
. Где<(CMD)
подстановка команды bash, а не перенаправление stdin.Для полноты картины вот как я это вижу в
34 разных ракурсах.Это точное описание, процитированное из официальной документации (выделено мной):
Но это все равно может быть непросто понять, поэтому в следующем разделе приведены два фактических примера, демонстрирующих, как предполагается использовать эти два подхода по-разному.
Поэтому их фактическое использование (предполагается) различное.
Если ваш проект
foo
будет выпущен как отдельная библиотека (то есть другие, вероятно, сделают этоimport foo
), тогда вы (и ваши последующие пользователи) захотите иметь гибкое объявление зависимости, так что ваша библиотека не будет (и не должна ) будьте «разборчивы» в том, какая именно версия ВАШИХ зависимостей должна быть. Итак, обычно ваш setup.py будет содержать такие строки:Если вы просто хотите каким-то образом «задокументировать» или «закрепить» вашу ТОЧНУЮ текущую среду для своего приложения
bar
, то есть вы или ваши пользователи хотели бы использовать ваше приложениеbar
как есть, то есть работающееpython bar.py
, вы можете заморозить свою среду, чтобы она всегда будет вести себя одинаково. В таком случае ваш файл требований будет выглядеть так:На самом деле, что мне использовать?
Если вы разрабатываете приложение,
bar
которое будет использоватьсяpython bar.py
, даже если это «просто сценарий для развлечения», вам все равно рекомендуется использовать файл requirements.txt, потому что, кто знает, на следующей неделе (а это Рождество) вы получите новый компьютер в подарок, так что вам нужно будет снова настроить там вашу точную среду.Если вы разрабатываете библиотеку,
foo
которая будет использоватьсяimport foo
, вам необходимо подготовить файл setup.py. Период. Но вы все равно можете одновременно предоставить файл requirements.txt, который может:(а) быть в
A==1.2.3
стиле (как объяснено в п. 2 выше);(б) или просто содержать волшебный сингл
.
что примерно равно «установить требования на основе setup.py» без дублирования. Лично я считаю, что этот последний подход размывает границы, добавляет путаницы и НЕ добавляет ценности, но, тем не менее, это уловка, основанная на подходе, упомянутом разработчиком упаковки Python Дональдом в его сообщении в блоге .
Различные нижние оценки.
Даже после того, как вы выполнили 3 вышеуказанных критерия и правильно решили, что ваша библиотека
hybrid-engine
будет использовать asetup.py
для объявления своей зависимостиengine>=1.2.0
, а ваше примерное приложениеreliable-car
будет использоватьrequirements.txt
для объявления своей зависимостиengine>=1.2.3
, даже если последняя версияengine
уже имеет версию 1.4.0. Как видите, ваш выбор для их нижней границы все еще немного отличается. И вот почему.hybrid-engine
зависит отengine>=1.2.0
того, потому что, гипотетически говоря, необходимая возможность «внутреннего сгорания» была впервые введенаengine 1.2.0
, и эта возможность является необходимостьюhybrid-engine
, независимо от того, могут ли быть некоторые (незначительные) ошибки внутри такой версии и исправлены в последующих версиях 1.2.1. , 1.2.2 и 1.2.3.reliable-car
зависит от,engine>=1.2.3
потому что это самая ранняя версия БЕЗ известных проблем. Конечно, в более поздних версиях есть новые возможности, например, «электродвигатель», представленный вengine 1.3.0
и «ядерный реактор»engine 1.4.0
, но они не являются необходимыми для проектаreliable-car
.источник
A==1.2.3
, а затем, если нижестоящий пакет вашей библиотеки зависитA==1.2.4
, теперь не будет способа удовлетворить оба. Решение минимизировать этот конфликт состоит в том, что ваша библиотека определяет диапазон, который, как вы знаете, будет работать. Предполагая, что многие апстрим-библиотеки уже подписаны на semver.org ,A>=1,<2
будет работать.foo
этоimport foo
даст вам? Тот хакерский принятый ответ в той ссылке, которую вы предоставили, служит прекрасным примером того, почему сопровождающий пакета «не должен и не должен быть придирчивым». :-) Теперь можно проголосовать за?