完全被所有管理依赖项的工具搞糊涂了吗?pip,venv,docker,conda,viralenvwrapper,pipeenv,…。你应该用哪一个呢?为什么我们会有这么多不同的工具呢?他们能一起工作吗?
没什么奇怪的。Python依赖项管理的世界一团糟,但是一旦您了解了这些工具以及它们存在的原因,在无法选择您最喜欢的工具的环境中选择您想要的工具和处理其他工具就会变得更容易。
在这篇文章的最后,我将简要描述每个工具,它为什么被创建,以及它正在处理的问题,你可以找到一个表格,总结了所有信息和人们使用的常见设置。
PIP(Package Installer For Python)是Python领域中最基本的软件包安装程序。它是随大多数Python安装一起预装的,所以您很可能永远不需要自己安装它。
安装软件包非常简单,只需运行pip install pytorch即可。该命令与PyPI(Python Package Index)对话,下载该包,并使其可用于当前的Python安装。
这是一种非常原始的工具。它对不同的Python版本或Jupyter内核一无所知。
最常见的用例是为每个应用程序创建一个环境。它确保应用程序之间不会共享软件包,也不会与系统的python安装共享软件包。每个环境都可以使用同一软件包的任何版本,它们不会发生冲突。
它们都是标准Python工具的一部分,处理非常不同的问题,并且在一起玩得很好。建议您使用pip在虚拟环境中安装软件包。
Python成为了一种广受欢迎的语言,所有主要的操作系统都开始在它的基础上构建,并将其捆绑在开箱即用的环境中。这就是为什么您可以在新安装的Linux或Mac OS上的终端中输入python,而不需要自己安装它。
但是用户应用程序也是用python构建的。而且他们通常需要不同版本的Python!这两者的结合产生了以某种方式运行不同版本的Python的需要,具体取决于应用程序。
创建Pyenv是为了解决在同一台机器上安装和切换不同版本的Python的问题。
它在开发者机器上是一个方便的工具,因为它保留了Python的系统版本(操作系统正常运行所需的),但可以为不同的应用程序安装不同的版本并在不同版本之间切换(基于当前路径、用户等)。
这里有一个在系统版本和3.6.3之间切换的示例。下次导航到该目录时,运行pyenv local 3.6.3将记住激活版本3.6.3。
皮耶夫和皮普是相辅相成的。您可以认为pyenv是pip的容器/shell。不管pyenv将其设置为什么值,pip都会为当前的python版本安装软件包。事实上,来自两个环境的pip命令是不同的二进制文件,彼此不认识。
一旦科学界开始认真使用Python,Python领域对包管理工具的需求就会增加。更具体地说,对于一些纯粹的计算工作来说,Python变得太慢了,因此就产生了麻木和迟钝。这些库并不是真正用python编写的。它们是用C语言编写的,只是包装成一个python库。
编译这样的库会带来一系列挑战1,因为它们(或多或少)必须在您的机器上编译,以获得最佳性能并与glibc等库正确链接。
CONDA是作为一体式解决方案推出的,用于为科学界管理Python环境。
它采取了一种不同的方法。不是在您的机器上使用脆弱的编译库过程,而是在您请求时预编译库并直接下载它们。不幸的是,该解决方案附带一个警告-Conda没有使用PyPI,这是最流行的Python包索引。
Conda有自己的套餐索引,有多个频道(蟒蛇频道由Conda的创建者维护,是最可靠的频道)。蟒蛇通道没有PyPI完整,而且这两个地方都存在的包通常比PyPI落后几个版本。其他渠道更新包的速度更快,但我强烈建议检查谁维护各自的包(通常不是库作者!)。
蟒蛇和Miniconda是Conda工具的不同发行版。Miniconda的目标是尽可能的最小化--它只安装了python和conda工具。蟒蛇还安装了数据科学工作流程中经常使用的另外160多个软件包。
如果您希望严格控制您运行的环境,我建议您安装miniconda并使用自下而上的方法构建环境。
CONDA是一个非常强大的工具。它解决了很多问题,所以它经常在某些轴上与其他工具发生冲突。可以让Conda与其他工具(例如,Pipenv)一起工作,但它需要对这两个工具(Python包加载)有更深的理解,而且不是经常使用的工具。
用于环境管理和为python包安装二进制包+pip的conda(conda+pip的最佳实践)。
Pipenv是一个开发工作流工具,由Popular Requests包的作者创建。除了使普通工作流流畅、管理有需求的文件(Pipfile)外,pipeenv还解决了以下问题:
它从PyPI加载包,因此不会遇到与Conda相同的问题。
Pipenv是第一个提到的认真解决环境可再生性问题的工具。保存Conda环境的标准方法(Environmental ment.yml)和pip/venv(requirements.txt)解决了部分问题:它们包含已安装的版本化软件包,但不包含其依赖项的版本。这为几类错误留下了空间,包括安全问题。
Pipenv通过维护Pipfile.lock文件来密封包版本,该文件包含虚拟环境中使用的所有包的特定版本。
Pipenv是围绕pip和其他几个工具的一个很好的包装器,这意味着它与pip交互非常好。如果您使用Pipenv Install<;Package>;而不是pip install<;Package>;,则可以省去几个手动步骤(更改Pipfile和Pipfile.lock)。
POLITE-“使Python打包和依赖管理变得容易”。诗歌最类似于pipeenv,他们经常争夺用户。诗歌要解决的主要问题有:
您可以看到,它与Pipenv没有太大不同。建议与pyenv配合使用。一旦这样做了,它就解决了pipeenv所做的所有问题,而且还有助于创建python包并将它们发布到PyPI。
POLITY与pyenv相辅相成,共同构成了管理工作流的完整解决方案。与pipeenv相同,它使用PyPI来安装软件包,因此一旦您开始使用POLITE,就不需要使用pip。
如果您想知道为什么有两个非常相似的工具,您并不孤单。主要的技术差异在于它们解析包的方式。这实际上是一个非常困难的问题,而诗歌在这一维度上是优越的。当您安装一个新的软件包时,它会更快地找出它到底要做什么,通常,它会更优雅地处理复杂的依赖关系图。
我的一般建议是,你可以选择任何一个,如果有人还没有为你正在工作的项目选择一个就行了。
Docker与Python依赖项管理没有任何关系,但人们经常在相同的上下文中谈论它,因此它的功能绝对值得一探。
Docker是用于创建、运行和管理容器的工具。您可以将容器视为非常轻量级的虚拟机。没有虚拟化,但它们与您的其余操作系统非常隔离。它是作为一种通用解决方案创建的,用于将生产软件打包,并在云中以可重复的、隔离的方式运行。
您可以运行我在Docker容器中解释的任何工具。Docker的好处是它给您带来的隔离避免了几个问题。例如,通常的设置是在不同的容器中运行每个应用程序。这意味着您可以在其中安装不同的Python版本,并且它们不会彼此认识。此外,由于应用程序在设计上是隔离的,因此不需要任何虚拟环境管理。
Docker是一项伟大的创新,它发生在我们在生产中运行软件的方式上,但我不推荐将其作为开发机器上Python依赖项管理问题的解决方案。
设置IDE来发现和调试Docker容器中的应用程序依赖关系通常不是一件容易的事,这使得开发变得更加困难。
安装与底层系统深度链接的库(如CUDA驱动程序)可能会变得相当棘手。
易学,用于管理依赖项管理的所有主要问题的良好设置。强烈推荐。每当我建立一个新项目时,我都会用到它。
有些人单独使用Conda。这种设置的主要问题是有些库在conda通道中不可用,因此您必须求助于使用conda+pip。
通用安装,使用Conda进行Python版本管理、虚拟环境管理和安装二进制依赖项。用于安装python包的pip。不幸的是,我已经提到过它有自己的问题,而且Conda通常是一个非常笨重的工具。
这是经常使用的,因为conda通过nb_conda_kernels扩展与jupyter进行了很好的集成。每当我必须在其他人设置的环境(如SageMaker)中使用conda时,我都会使用它。
用于管理不同Python版本和虚拟环境的轻量级设置。缺乏环境可再生性的解决方案,这是生产可靠运行的问题。
现在是2020年,但在不同的计算机设置上从源代码可靠地编译软件仍然是一个悬而未决的问题。没有很好的方法来管理不同版本的编译器、编译主程序所需的不同版本的库等。-↩