setuptools vs. distutils:为什么distutils仍然是一件事情?

Python有一个令人困惑的工具历史logging,可用于打包和描述项目:这包括标准库中的distutils分发distutils2setuptools等等。 似乎分发distutils2停止赞成setuptools ,这留下了两个相互竞争的标准。

据我所知, setuptoolsdistutils提供了更多的select(例如声明依赖关系,testing等),但它并不包含在python标准库中(还有?)。

Python打包用户指南 [ 1 ]现在推荐:

使用setuptools定义项目并创build源分配。

并解释说:

尽pipe您可以在很多项目中使用纯粹的distutils,但是它不支持在其他项目上定义依赖项,并且缺less一些便利的实用程序来正确自动填充由setuptools提供的程序包元数据。 在标准库之外,setuptools还提供了跨越不同版本的Python的更一致的function集,(与distutils不同),setuptools将被更新,以在所有支持的版本上生成即将到来的“Metadata 2.0”标准格式。

即使对于select使用distutils的项目,当pip直接从源代码安装这样的项目(而不是从预build的wheel文件安装),它实际上将使用setuptools来构build项目。

但是,查看各种项目的setup.py文件显示,这似乎不是一个实际的标准。 许多软件包仍然使用distutils,而那些支持setuptools的软件包通常会将setuptoolsdistutils混合使用 ,例如通过执行fallback导入:

try: from setuptools import setup except ImportError: from distutils.core import setup 

随后尝试find一种方法来编写可以由setuptoolsdistutils安装的设置。 这通常包括各种容易出错的依赖性检查方式,因为distutils不支持设置函数中的依赖关系。

为什么人们仍然在为支持distutils做出额外的努力 – setuptools不在标准库中是唯一的原因呢? distutils的优点是什么,并且是否有写仅支持setuptools的 setup.py文件的缺点。

看看这个。 它很好地解释了所有的包装方法,并可能在一定程度上帮助回答你的问题: 网页

Distutils仍然是Python打包的标准工具。 它包含在标准库(Python 2和Python 3.0到3.3)中。 这对于简单的Python发行版很有用,但缺乏特性。 它介绍了可以在setup.py脚本中导入的distutils Python包。

Setuptools是为了克服Distutils的限制而开发的,并没有包含在标准库中。 它引入了一个名为easy_install的命令行工具。 它还介绍了可以在setup.py脚本中导入的setuptools Python包,以及可以在代码中导入的pkg_resources Python包,以定位随分发安装的数据文件。 其中一个问题是,它会修复distutils Python包。 它应该与pip很好地工作。 最新版本于2013年7月发布。

所以,正如你所看到的,setuptools应该被认为是distutils,而且我看到你的问题来自哪里,但是我没有看到distutils很快失去了支持,简而言之,在很多情况下(特别是传统程序)事实上的标准。 而且你可能知道在传统程序中改变这些东西可能会非常痛苦,并且会带来很多问题,比如不兼容,这会导致开发人员不得不重写源代码。 所以有这样的事实,distutils是标准python库的一部分,而setuptools则不是。 所以,如果你正在创build一个Python程序,在这个时代,使用setuptools,但是请记住,没有distutils,setuptools将永远不会存在。

有几个原因,我们仍然谈论和使用distutils,即使setuptools毫无疑问是更好的工具集。

首先,distutils到处可用。 如果您打算build立一个与他人共享的模块,而且没有任何复杂的要求,那么可以保证在您的工作机器上可用。 如果您必须支持较旧版本的python,或者如果您发现自己在陌生的环境中工作,这一点尤其重要。

其次,setuptools提供distutils的增强。 因此,它是在distutils工具集之后build模的,并从那里取得了所有的结构。 setuptools的文档假设读者熟悉distutils,只logging如何增强基本工具集。 你可以想到,distutils定义了方言,setuptools增强了方言。

我个人对新项目的方法是从我将要使用distutils的假设开始的。 只有当项目发展到需要setuptools的function,我才能升级。 setuptools是distutils的一个替代品,这是对我的setup.py的一个改变。

是setuptools不在标准库中的唯一原因

这是一个原因。 以下是从NumPy setup.py

 if len(sys.argv) >= 2 and ('--help' in sys.argv[1:] or sys.argv[1] in ('--help-commands', 'egg_info', '--version', 'clean')): # Use setuptools for these commands (they don't work well or at all # with distutils). For normal builds use distutils. try: from setuptools import setup except ImportError: from distutils.core import setup 

所以NumPy更喜欢setuptools如果它能find它的话。 但是SciPy过去一直这样做,直到在某些情况下修补偏好distutils 。 引用提交日志:

 Setuptools sets mode +x on the test scripts, so that Nose refuses to run them. Better not do that. 

当然, setuptoolsdistribute之间的合并应该在适当的时候解决所有这些问题,但是很多软件包仍然需要支持Python 2.6的安装。

基本上,这是由于责任分工。

setuptools不是Python标准库的一部分,因为它由第三方而不是Python核心团队维护。 这意味着,除其他外:

  • 它不被核心testing套件覆盖,核心function也不依赖它
  • 它本身并不设置附加模块的核心标准(它们的位置,导入方式,C扩展的二进制接口等)。
  • 它是独立于Python发行版而更新和发布的

实际上,核心团队已经缩小了这些困境的范围,为自己保留了“核心标准”和“最低限度必要的编译”部分, 而把所有的东西 (扩展的编译/封装格式/任何支持) 都留给了 第三方。 以前覆盖这些“扩展部分”的代码对于向后兼容性而言是陈旧的。

从分布式Python模块 – Python 2.7.12文档 :

虽然直接使用distutils正在被淘汰,但它仍然为现有的包装和分销基础设施奠定了基础,它不仅是标准图书馆的一部分,而且它的名字以其他方式存在(例如邮寄名称列表用于协调Python包装标准的开发)。

由于上述原因,其他操作系统的软件包同样可能会分别提供setuptoolspip

  • 而且当系统中已经有另外一个软件包pipe理器的时候,它们不是必需的 – 或者甚至对可维护性是不利的。