59

我的目标是分发一个 Python 包,其中包含其他几个广泛使用的 Python 包作为依赖项。我的包依赖于编写良好的、带有 Pypi 索引的包,如 pandas、scipy 和 numpy,并在 setup.py 中指定需要某些版本或更高版本,例如“numpy >= 1.5”。

我发现对于不是Python 打包专家(即使他们知道如何编写 Python)的精通 Unix 的用户来说,安装像我这样的包是非常令人沮丧和几乎不可能的,即使在使用应该易于使用的包管理器时也是如此. 我想知道是否有人可以提供这个痛苦过程的替代方案,或者我的经验是否只是反映了 Python 打包和分发当前非常困难的状态。

假设用户将您的软件包下载到他们的系统上。大多数人会尝试“天真地”安装它,使用类似的东西:

$ python setup.py install

因为如果你在谷歌上搜索安装 Python 包的说明,通常会出现这种情况。对于绝大多数用户来说,这将失败,因为大多数用户在他们的 Unix/Linux 服务器上没有 root 访问权限。通过更多搜索,他们会发现“--prefix”选项并尝试:

$ python setup.py install --prefix=/some/local/dir

--prefix由于用户不了解 Python 打包的复杂性,他们会选择任意目录作为"~/software/mypackage/". 它不会是所有其他 Python 包所在的干净策划的目录,因为同样,大多数用户并不知道这些细节。如果他们安装另一个包“myotherpackage”,他们可能会通过它"~/software/myotherpackage",你可以想象这将如何导致令人沮丧的黑客攻击PYTHONPATH和其他并发症。

继续安装过程,一旦用户尝试使用该包,调用"setup.py install"with"--prefix"也将失败,即使它似乎已正确安装,因为可能缺少其中一个依赖项(例如 pandas、scipy 或 numpy)和一个包不使用管理器。他们将尝试单独安装这些软件包。即使成功,PYTHONPATH由于给定的非标准目录,包将不可避免地不在"--prefix",耐心的用户将涉足其修改PYTHONPATH以使依赖项可见。

在这个阶段,精通 Python 的朋友可能会告诉用户,他们应该使用包管理器"easy_install"(主流管理器)来安装软件并处理依赖关系。安装后"easy_install",这可能很困难,他们会尝试:

$ easy_install setup.py 

这也会失败,因为用户通常没有权限在生产 Unix 服务器上全局安装软件。通过更多阅读,他们将了解该"--user"选项,并尝试:

$ easy_install setup.py --user 

他们会得到错误:

usage: easy_install [options] requirement_or_url ...
   or: easy_install --help

error: option --user not recognized

他们会非常困惑,为什么他们easy_install没有--user选项,而在线上有明确的页面描述了该选项。他们可能会尝试将其升级easy_install到最新版本并发现它仍然失败。

如果他们继续咨询Python打包专家,他们会发现有两个版本easy_install都命名为“easy_install"以便最大程度地混淆”,但一个是“distribute”,另一个是“setuptools”。恰好是只有"easy_install"支持和"distribute"绝大多数"--user"服务器/系统管理员安装"setuptools"easy_install所以本地安装是不可能的。请记住,对于非 Python 包管理专家的人来说,和之间的这些区别"distribute""setuptools"没有意义的并且难以理解。

在这一点上,即使是尝试安装我的软件包的最坚定、最精明和耐心的用户,我也会失去 90% 的用户——这是理所当然的!他们想安装一个碰巧用 Python 编写的软件,而不是成为最先进的 Python 包分发方面的专家,这太令人困惑和复杂了。他们会放弃并为浪费的时间感到沮丧。

继续询问更多 Python 专家的极少数用户将被告知他们应该pip/virtualenv使用easy_install. 安装pipvirtualenv弄清楚这些工具是如何工作的,以及它们与传统"python setup.py""easy_install"调用的不同之处本身就是耗时且困难的,对于只想安装一个简单的 Python 软件并使用它的用户来说,要求也太高了。即使是那些追求这条道路的人也会对他们安装的任何依赖项是否仍然可用easy_install或者是否需要从头开始重新安装所有依赖项感到困惑。setup.py install --prefixpip/virtualenv

如果一个或多个有问题的包依赖于安装与默认版本不同的 Python 版本,则此问题会更加严重。确保您的 Python 包管理器使用的是您想要的 Python 版本,以及确保所需的依赖项安装在相关的 Python 2.x 目录而不是 Python 2.y 中的困难,将让用户无休止地感到沮丧,以至于他们肯定会在那个阶段放弃。

有没有更简单的方法来安装 Python 软件,不需要用户深入研究 Python 包、路径和位置的所有这些技术细节?例如,我不是 Java 大用户,但我偶尔会使用一些 Java 工具,并且不记得曾经担心我正在安装的 Java 软件的 X 和 Y 依赖关系,而且我不知道 Java 是如何打包的管理作品(我很高兴我不这样做——我只是想使用一个碰巧用 Java 编写的工具。) .

是否有 Python 的等价物?以一种不依赖于用户必须追逐所有这些依赖项和版本的方式分发软件的方法?一种可能将所有相关包编译成独立的东西的方法,可以下载并用作二进制文件?

我想强调的是,即使将软件包分发给精通的 Unix 用户的狭隘目标也会发生这种挫败感,这使问题变得更简单,无需担心跨平台问题等。我假设用户精通 Unix,甚至可能了解 Python,但只是不了解(也不想被告知)Python 打包的来龙去脉以及不同包管理器的无数内部复杂性/竞争。这个问题的一个令人不安的特点是,即使您的所有 Python 包依赖项都是众所周知的、编写良好且维护良好的 Pypi 可用包(如 Pandas、Scipy 和 Numpy),它也会发生。这不像是我依赖于一些不是格式正确的包的晦涩依赖:相反,我使用的是许多人可能依赖的最主流的包。

对此的任何帮助或建议将不胜感激。我认为 Python 是一门很棒的语言,拥有很棒的库,但我发现几乎不可能以一种易于人们在本地安装并运行的方式分发我用它编写的软件(一旦它具有依赖项)。我想澄清一下,我正在编写的软件不是用于编程使用的 Python 库,而是具有用户作为单独程序运行的可执行脚本的软件。谢谢。

4

2 回答 2

14

我们还开发依赖于 numpy、scipy 和其他 PyPI 包的软件项目。毫无疑问,目前用于管理远程安装的最佳工具是zc.buildout。它非常易于使用。您从他们的网站下载引导脚本并将其与您的包一起分发。您编写了一个“本地部署”文件,通常称为buildout.cfg,它解释了如何在本地安装包。您将bootstrap.py文件和buildout.cfg您的包一起发送 - 我们使用MANIFEST.in我们的 python 包中的文件来强制使用 PyPI 分发的 zip 或 tar 球嵌入这两个文件。当用户解包时,它应该执行两个命令:

$ python bootstrap.py # this will download zc.buildout and setuptools
$ ./bin/buildout # this will build and **locally** install your package + deps

该包已编译,所有依赖项都安装在本地,这意味着安装您的包的​​用户甚至不需要 root 权限,这是一个附加功能。脚本(通常)放在 下./bin,因此用户可以在此之后执行它们。zc.buildout用于setuptools与 PyPI 交互,因此您期望的一切都可以开箱即用。

如果所有这些功能还不够,您可以很容易地进行扩展zc.buildout——您可以创建所谓的“配方”,帮助用户创建额外的配置文件、从网上下载其他东西或实例化自定义程序。zc.buildout网站包含一个视频教程,详细解释了如何使用 buildout 以及如何扩展它。我们的项目Bob广泛使用 buildout 来分发包以供科学使用。如果您愿意,请访问以下页面,其中包含为我们的开发人员提供的详细说明,了解他们如何设置他们的 python 包,以便其他人可以使用zc.buildout.

于 2013-02-02T20:24:00.600 回答
6

我们目前正在努力让用户更容易开始以独立于平台的方式安装 Python 软件(特别是请参阅https://python-packaging-user-guide.readthedocs.org/en/latest/future.htmlhttp://www.python.org/dev/peps/pep-0453/

目前,easy_install 的两个竞争版本的问题已经解决,竞争的 fork “distribute”被合并到 setuptools 开发主线。

当前关于 Python 软件跨平台分发和安装的最佳建议可在此处获取:https ://packaging.python.org/

于 2013-09-15T12:11:24.970 回答