Python requirements.txt 与 setup.py
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43658870/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
requirements.txt vs setup.py
提问by lucy
I started working with Python. I've added requirements.txt
and setup.py
to my project. But, I am still confused about the purpose of both files. I have read that setup.py
is designed for redistributable things and that requirements.txt
is designed for non-redistributable things. But I am not certain this is accurate.
我开始使用 Python。我已将requirements.txt
和添加setup.py
到我的项目中。但是,我仍然对这两个文件的用途感到困惑。我读过它setup.py
是为可再发行的东西而requirements.txt
设计的,而它是为不可再发行的东西而设计的。但我不确定这是否准确。
How are those two files truly intended to be used?
这两个文件真正打算如何使用?
采纳答案by AndreasT
requirements.txt
要求.txt
This helps you to set up your development environment. Programs like pip
can be used to install all packages listed in the file in one fell swoop. After that you can start developing your python script. Especially useful if you plan to have others contribute to the development or use virtual environments.
This is how you use it:
这有助于您设置开发环境。像这样的程序pip
可用于一举安装文件中列出的所有软件包。之后你就可以开始开发你的python脚本了。如果您计划让其他人参与开发或使用虚拟环境,则特别有用。这是你如何使用它:
pip install -r requirements.txt
setup.py
设置文件
This allows you to create packages that you can redistribute. This script is meant to install your package on the end user's system, not to prepare the development environment as pip install -r requirements.txt
does.
See this answerfor more details on setup.py.
这允许您创建可以重新分发的包。此脚本旨在将您的软件包安装到最终用户的系统上,而不是像pip install -r requirements.txt
那样准备开发环境。有关setup.py 的更多详细信息,请参阅此答案。
The dependencies of your project are listed in both files.
项目的依赖项都列在这两个文件中。
回答by init_js
The short answer is that requirements.txt
is for listing package requirements only. setup.py
on the other hand is more like an installation script. If you don't plan on installing the python code, typically you would only need requirements.txt
.
简短的回答是这requirements.txt
仅用于列出包要求。setup.py
另一方面更像是一个安装脚本。如果您不打算安装 python 代码,通常您只需要requirements.txt
.
The file setup.py
describes, in addition to the package dependencies, the set of files and modules that should be packaged (or compiled, in the case of native modules (i.e., written in C)), and metadata to add to the python package listings (e.g. package name, package version, package description, author, ...).
setup.py
除了包依赖项之外,该文件还描述了应该打包(或编译,在本机模块(即用 C 语言编写)的情况下)的文件和模块集,以及要添加到 python 包列表中的元数据(例如包名称,包版本,包描述,作者,...)。
Because both files list dependencies, this can lead to a bit of duplication. Read below for details.
因为这两个文件都列出了依赖关系,所以这可能会导致一些重复。阅读下文了解详情。
requirements.txt
要求.txt
This file lists python package requirements. It is a plain text file (optionally with comments) that lists the package dependenciesof your python project (one per line). It does notdescribe the way in which your python package is installed. You would generally consume the requirements file with pip install -r requirements.txt
.
此文件列出了 python 包要求。它是一个纯文本文件(可选带有注释),其中列出了您的 Python 项目的包依赖项(每行一个)。它没有描述安装 python 包的方式。您通常会使用pip install -r requirements.txt
.
The filename of the text file is arbitrary, but is often requirements.txt
by convention. When exploring source code repositories of other python packages, you might stumble on other names, such as dev-dependencies.txt
or dependencies-dev.txt
. Those serve the same purpose as dependencies.txt
but generally list additional dependencies of interest to developers of the particular package, namely for testing the source code (e.g. pytest, pylint, etc.) before release. Users of the package generally wouldn't need the entire set of developer dependencies to run the package.
文本文件的文件名是任意的,但通常requirements.txt
是约定俗成的。在探索其他 Python 包的源代码存储库时,您可能会偶然发现其他名称,例如dev-dependencies.txt
或dependencies-dev.txt
。这些服务与dependencies.txt
特定包的开发人员感兴趣的其他依赖项具有相同的目的,但通常会列出其他依赖项,即在发布之前测试源代码(例如 pytest、pylint 等)。该包的用户通常不需要整套开发人员依赖项来运行该包。
If multiplerequirements-X.txt
variants are present, then usually one will list runtime dependencies, and the other build-time, or test dependencies. Some projects also cascade their requirements file, i.e. when one requirements file includes another file (example). Doing so can reduce repetition.
如果requirements-X.txt
存在多个变体,那么通常一个会列出运行时依赖项,另一个列出构建时或测试依赖项。一些项目还级联其需求文件,即当一个需求文件包含另一个文件时(示例)。这样做可以减少重复。
setup.py
设置文件
This is a python script which uses the setuptools
module to define a python package (name, files included, package metadata, and installation). It will, like requirements.txt
, also list runtime dependencies of the package. Setuptools is the de-facto way to build and install python packages, but it has its shortcomings, which over time have sprouted the development of new "meta-package managers", like pip. Example shortcomings of setuptools are its inability to install multiple versions of the same package, and lack of an uninstall command.
这是一个 python 脚本,它使用setuptools
模块来定义 python 包(名称、包含的文件、包元数据和安装)。它也会像 一样requirements.txt
列出包的运行时依赖项。Setuptools 是构建和安装 python 包的事实上的方法,但它也有它的缺点,随着时间的推移,它催生了新的“元包管理器”的开发,比如 pip。setuptools 的示例缺点是它无法安装同一软件包的多个版本,并且缺少卸载命令。
When a python user does pip install ./pkgdir_my_module
(or pip install my-module
), pip will run setup.py
in the given directory (or module). Similarly, any module which has a setup.py
can be pip
-installed, e.g. by running pip install .
from the same folder.
当 python 用户执行pip install ./pkgdir_my_module
(或pip install my-module
)时,pip 将setup.py
在给定目录(或模块)中运行。类似地,setup.py
可以pip
安装任何具有 的模块,例如通过pip install .
从同一文件夹运行。
Do I really need both?
我真的需要两者吗?
Short answer is no, but it's nice to have both. They achieve different purposes, but they can both be used to list your dependencies.
简短的回答是否定的,但两者兼得很好。它们实现不同的目的,但它们都可用于列出您的依赖项。
There is one trick you may consider to avoid duplicating your list of dependencies between requirements.txt
and setup.py
. If you have written a fully working setup.py
for your package already, and your dependencies are mostly external, you could consider having a simple requirements.txt
with only the following:
您可以考虑使用一种技巧来避免在requirements.txt
和之间复制依赖项列表setup.py
。如果您已经setup.py
为您的包编写了一个完整的工作包,并且您的依赖项主要是外部的,您可以考虑使用一个requirements.txt
只包含以下内容的简单程序:
# requirements.txt
#
# installs dependencies from ./setup.py, and the package itself,
# in editable mode
-e .
# (the -e above is optional). you could also just install the package
# normally with just the line below (after uncommenting)
# .
The -e
is a special pip install
option which installs the given package in editablemode. When pip -r requirements.txt
is run on this file, pip will install your dependencies via the list in ./setup.py
. The editable option will place a symlink in your install directory (instead of an egg or archived copy). It allows developers to edit code in place from the repository without reinstalling.
这-e
是一个特殊pip install
选项,它以可编辑模式安装给定的包。当pip -r requirements.txt
在这个文件上运行时,pip 将通过./setup.py
. 可编辑选项将在您的安装目录中放置一个符号链接(而不是鸡蛋或存档副本)。它允许开发人员在不重新安装的情况下从存储库就地编辑代码。
You can also take advantage of what's called "setuptools extras" when you have both files in your package repository. You can define optional packages in setup.py under a custom category, and install those packages from just that category with pip:
当您的包存储库中有两个文件时,您还可以利用所谓的“setuptools extras”。您可以在 setup.py 中的自定义类别下定义可选包,并使用 pip 从该类别安装这些包:
# setup.py
from setuptools import setup
setup(
name="FOO"
...
extras_require = {
'dev': ['pylint'],
'build': ['requests']
}
...
)
and then, in the requirements file:
然后,在需求文件中:
# install packages in the [build] category, from setup.py
# (path/to/mypkg is the directory where setup.py is)
-e path/to/mypkg[build]
This would keep all your dependency lists inside setup.py.
这会将所有依赖项列表保存在 setup.py 中。
Note: You would normally execute pip and setup.py from a sandbox, such as those created with the program virtualenv
. This will avoid installing python packages outside the context of your project's development environment.
注意:您通常会从沙箱(例如使用程序创建的沙箱)执行 pip 和 setup.py virtualenv
。这将避免在项目开发环境的上下文之外安装 python 包。
回答by RayLuo
For the sake of completeness, here is how I see it in 34 different angles.
为了完整起见,以下是我从34 个不同角度看待它的方式。
- Their design purposes are different
- 它们的设计目的不同
This is the precise description quoted from the official documentation(emphasis mine):
这是从官方文档中引用的准确描述(重点是我的):
Whereas install_requires (in setup.py) defines the dependencies for a single project, Requirements Files are often used to define the requirements for a complete Python environment.
Whereas install_requires requirements are minimal, requirements files often contain an exhaustive listing of pinned versions for the purpose of achieving repeatable installations of a complete environment.
install_requires(在 setup.py 中)定义了单个项目的依赖项,而需求文件通常用于定义完整 Python 环境的需求。
尽管 install_requires 要求最低,但要求文件通常包含固定版本的详尽列表,目的是实现完整环境的可重复安装。
But it might still not easy to be understood, so in next section, there come 2 factual examples to demonstrate how the 2 approaches are supposed to be used, differently.
但它可能仍然不容易理解,因此在下一节中,将提供 2 个事实示例来演示应该如何以不同的方式使用这两种方法。
Their actual usages are therefore (supposed to be) different
If your project
foo
is going to be released as a standalone library (meaning, others would probably doimport foo
), then you (and your downstream users) would want to have a flexible declaration of dependency, so that your library would not (and it must not) be "picky" about what exact version of YOUR dependencies should be. So, typically, your setup.py would contain lines like this:install_requires=[ 'A>=1,<2', 'B>=2' ]
If you just want to somehow "document" or "pin" your EXACT current environment for your application
bar
, meaning, you or your users would like to use your applicationbar
as-is, i.e. runningpython bar.py
, you may want to freeze your environment so that it would always behave the same. In such case, your requirements file would look like this:A==1.2.3 B==2.3.4 # It could even contain some dependencies NOT strickly required by your library pylint==3.4.5
In reality, which one do I use?
If you are developing an application
bar
which will be used bypython bar.py
, even if that is "just script for fun", you are still recommended to use requirements.txt because, who knows, next week (which happens to be Christmas) you would receive a new computer as a gift, so you would need to setup your exact environment there again.If you are developing a library
foo
which will be used byimport foo
, you have to prepare a setup.py. Period. But you may still choose to also provide a requirements.txt at the same time, which can:(a) either be in the
A==1.2.3
style (as explained in #2 above);(b) or just contain a magical single
.
.
which would roughly equal to "install the requirements based on setup.py" while without duplication. Personally I consider this last approach kind of blurs the line, adds to the confusion and does NOT really add value, but it is nonetheless a trick derived from an approach mentioned by Python packaging maintainer Donald in his blog post.
Different lower bounds.
Even after you have followed the above 3 criteria and correctly decided that your library
hybrid-engine
would use asetup.py
to declare its dependencyengine>=1.2.0
, and your sample applicationreliable-car
would userequirements.txt
to declare its dependencyengine>=1.2.3
, even though the latest version ofengine
is already at 1.4.0. As you see, your choice for their lower bound number are still subtly different. And here is why.hybrid-engine
depends onengine>=1.2.0
because, hypothetically speaking, the needed "internal combustion" capability was first introduced inengine 1.2.0
, and that capability is the necessity ofhybrid-engine
, regardless of whether there might be some (minor) bugs inside such version and been fixed in subsequent versions 1.2.1, 1.2.2, and 1.2.3.reliable-car
depends onengine>=1.2.3
because that is the earliest version WITHOUT known issues, so far. Sure there are new capabilities in later versions, say, "electric motor" introduced inengine 1.3.0
, and "nuclear reactor" introduced inengine 1.4.0
, but they are not necessary for projectreliable-car
.
因此,它们的实际用途(应该)是不同的
如果您的项目
foo
将作为独立库发布(也就是说,其他人可能会这样做import foo
),那么您(和您的下游用户)会希望有一个灵活的依赖声明,这样您的库就不会(并且不能) 对您的依赖项的确切版本应该是“挑剔”。因此,通常,您的 setup.py 将包含这样的行:install_requires=[ 'A>=1,<2', 'B>=2' ]
如果您只是想以某种方式为您的应用程序“记录”或“固定”您当前的确切环境
bar
,这意味着您或您的用户希望bar
按原样使用您的应用程序,即运行python bar.py
,您可能希望冻结您的环境,以便它总是表现得一样。在这种情况下,您的需求文件将如下所示:A==1.2.3 B==2.3.4 # It could even contain some dependencies NOT strickly required by your library pylint==3.4.5
实际上,我使用哪一种?
如果您正在开发
bar
将由 使用的应用程序python bar.py
,即使那是“只是为了好玩的脚本”,仍然建议您使用 requirements.txt 因为,谁知道呢,下周(恰好是圣诞节)您会收到一个新计算机作为礼物,因此您需要再次在那里设置您的确切环境。如果您正在开发一个
foo
将由 使用的库import foo
,您必须准备一个 setup.py。时期。但是你仍然可以选择同时提供一个requirements.txt,它可以:(a) 要么符合
A==1.2.3
风格(如上面第 2 条所述);(b) 或者只包含一个神奇的单曲
.
.
这大致相当于“安装基于 setup.py 的要求”而没有重复。就我个人而言,我认为最后一种方法模糊了界限,增加了混乱并且并没有真正增加价值,但它仍然是从 Python 打包维护者 Donald 在他的博客文章中提到的方法中衍生出来的一种技巧。
不同的下限。
即使您遵循了上述 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
。