如何轻松分发具有Python模块依赖的Python软件? Unix上的Python包安装问题

2024-05-09 05:30:14 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

假设用户将您的包下载到他们的系统上。大多数人会尝试“天真地”安装它,使用如下方法:

$ python setup.py install

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

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

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

继续安装过程,一旦用户尝试使用包,对"setup.py install""--prefix"的调用也将失败,即使该包似乎已正确安装,因为其中一个依赖项可能丢失(例如pandas、scipy或numpy),并且没有使用包管理器。他们将尝试单独安装这些软件包。即使成功,由于给"--prefix"的非标准目录,包也不可避免地不会在PYTHONPATH中,患者用户将尝试修改他们的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"中的"easy_install"支持"--user",并且绝大多数服务器/sys管理员安装"setuptools"easy_install,因此无法进行本地安装。请记住,"distribute""setuptools"之间的这些区别对于那些不是Python包管理专家的人来说是毫无意义和难以理解的。

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

很少有用户继续询问更多的Python专家,他们会被告知应该使用pip/virtualenv,而不是easy_install。安装pipvirtualenv并找出这些工具是如何工作的,以及它们与传统的"python setup.py""easy_install"调用有何不同,这本身既费时又困难,而且对于只想安装一个简单的Python软件并使用它的用户来说,要求太多了。即使是那些追求这条道路的人也会困惑,他们用easy_installsetup.py install --prefix安装的任何依赖项是否仍然可以用pip/virtualenv使用,或者是否需要从头重新安装所有东西。

如果所讨论的一个或多个包依赖于安装与默认版本不同的Python版本,则此问题会更加严重。要确保Python包管理器使用的是您希望它使用的Python版本,并且所需的依赖项安装在相关的Python 2.x目录中,而不是python2.y目录中,这一困难会让用户非常沮丧,以至于他们一定会在这一阶段放弃。

有没有一种更简单的安装Python软件的方法,不需要用户深入研究Python包、路径和位置的所有这些技术细节?例如,我不是一个大的Java用户,但我偶尔也会使用一些Java工具,而且我不记得曾经担心过我安装的Java软件的X和Y依赖性,我不知道Java包管理是如何工作的(我很高兴我没有——我只是想使用一个碰巧用Java编写的工具。)我的记忆是,如果你下载了一个Jar,你只需要得到它,它就会工作。

对于Python有等价物吗?一种不依赖于用户追踪所有依赖项和版本的软件分发方式?一种可能将所有相关包编译成可以下载并用作二进制文件的自包含包的方法?

我想强调的是,这种挫败感甚至发生在将包分发给精明的Unix用户的狭隘目标上,这使得问题变得更简单,因为不必担心跨平台问题等。我假设用户精通Unix,甚至可能知道Python,但只是不知道(也不想知道)关于Python打包的内部和外部,以及不同包管理器的无数内部复杂性/竞争。这个问题的一个令人不安的特性是,即使所有Python包依赖项都是众所周知、编写良好且维护良好的Pypi可用包(如Pandas、Scipy和Numpy),也会发生这种情况。这并不是说我依赖于某些格式不正确的包的模糊依赖关系:相反,我使用的是许多人可能依赖的最主流的包。

如有任何帮助或建议,将不胜感激。我认为Python是一种很好的语言,它有很好的库,但我发现实际上不可能以一种便于人们在本地安装和运行的方式分发我在其中编写的软件(一旦它有依赖项)。我想澄清的是,我正在编写的软件不是一个用于编程的Python库,而是一个具有可执行脚本的软件,用户可以将其作为单独的程序运行。谢谢。


Tags: install用户py版本目录管理器prefix软件
2条回答

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

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

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

如果没有足够的能力,您可以很容易地扩展zc.buildout-您可以创建所谓的“配方”,帮助用户创建额外的配置文件、从网络下载其他内容或实例化自定义程序。zc.buildout网站包含一个视频教程,详细说明如何使用buildout以及如何扩展它。我们的项目Bob广泛使用buildout来分发科学使用的包。如果您愿意,请visit the following page,其中包含有关如何设置python包的详细说明,以便其他人可以使用zc.buildout在本地构建和安装它们。

我们目前正在努力让用户更容易开始以独立于平台的方式安装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/

相关问题 更多 >