虚拟环境和pyenv之间有什么关系?

219

我最近学会了如何在工作流程中使用virtualenv和virtualenvwrapper,但是我在几个指南中看到了pyenv的提及,但是我似乎无法理解pyenv是什么以及它与virtualenv有何不同/相似之处。 pyenv是更好/更新的virtualenv替代品还是补充工具? 如果是后者,它有什么不同之处,这两个工具(如果适用)如何配合使用?


3
然而,有另一种名为pyenv的替代方案具有几个显著优点。 - Martijn Pieters
15
不要像我一样,混淆 pyenvpyvenv - User
3个回答

194

Pyenvvirtualenv是非常不同的工具,其工作方式也不同,用途各异:

  • Pyenv是一个bash扩展 - 不适用于Windows - 它截取您对python、pip等的调用,将它们指向系统中的几个python工具链之一。因此,您始终可以使用所选Python版本中安装的所有库 - 对于需要在不同版本的Python之间切换的用户来说非常好。

  • VirtualEnv纯粹是Python代码,因此可以在任何地方运行。它会复制一个本地的Python和pip环境,可选特定版本,该环境可能包括链接到当前系统工具链,如果没有,则可以将已知子集的库安装到该环境中。因此,它几乎肯定更适合测试和部署,因为您知道使用了哪些库以及它们的哪些版本,并且全局更改不会影响您的模块。

venv python > 3.3

请注意,从Python 3.3开始,内置了名为venv的VirtualEnv实现(在某些安装中还有一个称为pyvenv的包装器 - 此包装器在Python 3.6中已弃用),应优先使用它。为避免可能出现的包装器问题,直接使用它通常是一个好主意,方法是使用/path/to/python3 -m venv desired/env/path,或者在Windows上使用优秀的py Python选择器和py -3 -m venv desired/env/path。它将创建指定目录desired/env/path,并配置和填充适当的内容。总的来说,它非常像使用VirtualEnv。

其他工具

有几个值得提及和考虑的工具,它们可以帮助使用以上任一工具:

  • VirtualEnvWrapper 管理和简化VirtualEnv的使用和管理 - 跨平台
  • pyenv-virtualenv通过pyenv-installer安装,它为PyEnv提供了管理和与VirtualEnv交互的工具 - 你可以拥有一个基本安装包含多个Python版本,并在其中创建隔离的环境 - 仅限Linux / OS-XJohann Visagie建议使用。
  • PyInstaller 可以将你的Python代码(可能是在VirtualEnv下开发和测试的)打包起来,以便在没有 你的版本 Python的平台上运行。请注意,它不是交叉编译器,你需要一个Windows(虚拟)机器来构建Windows安装程序等,但即使在您可以确保Python已安装但无法确保Python版本和库与您的代码兼容时,它也很方便。

3
值得一提的是,pyenv-virtualenv 是一个 pyenv 插件,它可以使 pyenv 和 virtualenv 无缝地协同工作。如果你使用 pyenv-installer 安装了 pyenv,那么 pyenv-virtualenv 已经包含在内了。
  • https://github.com/yyuu/pyenv-virtualenv
  • https://github.com/yyuu/pyenv-installer
- wjv
2
现在标准库中的venv怎么样? - Flimm
1
@Flimm:从Python 3.3开始,venv已成为标准库的一部分,应该使用它来代替virtualenv,因为它经常被描述为“正确实现的virtualenv”-https://www.reddit.com/r/learnpython/comments/4hsudz/pyvenv_vs_virtualenv/ - Steve Barnes
3
pyenv-virtualenv不再仅限于Linux系统,至少现在不是了。在MacOS上可以使用Homebrew包进行轻松安装。 - Turn
2
最近我们开发了一个名为 pyenv-win 的 Windows 平台 pyenv。如果有需要的话可以看一下。 - Kiran Kumar Kotari

40

简短版:

  • virtualenv 允许您通过从现有的Python安装中克隆来创建本地(每个目录),独立的Python安装
  • pyenv 允许您安装(从源代码构建)不同版本的Python,这些版本可以并存;然后您可以使用 virtualenv 克隆它们或使用 pyenv 选择任何时候要运行哪个版本

详细版:

Virtualenv 允许您在项目的子目录中创建自定义Python安装。这是通过从系统上某个现有的Python安装进行克隆来完成的(一些文件将被复制,一些则会被重用/共享以节省空间)。因此,每个项目都可以拥有其各自的 python (甚至可以有多个),位于其各自的虚拟环境中。即使某些/所有虚拟环境具有相同版本的 python(例如3.8.5),也完全没有冲突-它们是分离的且互相不知道对方的存在。如果想要从 shell 使用其中任何一个 python,必须先激活它(通过运行脚本临时修改您的 PATH,确保该虚拟环境的 bin/ 目录最先被调用)。从那时起,调用 python(或pip等)将调用该虚拟环境的版本,直到您将其 deactivate(恢复 PATH 为原始状态)。还可以通过绝对路径调用进入虚拟环境中的Python-这在从脚本中调用Python时可能会很有用。

Pyenv的覆盖范围比virtualenv更广。它用于安装(从源代码构建)Python的任意版本(它持有可用版本的注册表)。默认情况下,它们都安装在~/.pyenv下,因此它们比virtualenv“更全局”。然后,它允许您配置在使用python命令(没有virtualenv的情况下)时要运行哪个版本的Python。这可以在全局级别或单独的目录中完成(通过在目录中放置一个.python-version文件)。这是通过将 pyenv 的 shim python 脚本加入到您的PATH中(与在 virtualenv 中不同,永久性的),然后决定要调用哪个“真实”的python来完成的。您甚至可以配置pyenv调用其中一个虚拟环境的python(使用pyenv-virtualenv插件)。您还可以复制Python版本(给它们不同的名称)并让它们分叉。

使用pyenv可以方便地安装Python以供后续使用 virtualenv。


2

我对这个问题的解释不够好而感到沮丧,以至于我要在这里发布自己的答案,尽管我并不完全确定这是完全准确和完整的。我认为这是因为多年来这个领域已经有了很多替代方案,而“推荐”的工具也发生了很大变化。

基本区别:Python二进制文件与Python库

在基本层面上,当您想要开始运行任何特定的Python项目时,您需要两个东西:Python二进制文件(及其内置函数)和一些Python第三方库;但您不仅有一个项目:这就是为什么您需要工具。

明确的定义:“Python”与“环境”

  1. "Python"。人们经常在说到“Python”时,指的不仅仅是二进制文件,还包括库和第三方安装程序。要运行Python,您需要实际的二进制文件;一个单独的文件,在一个位置上,例如/usr/bin/python3。这也带有相同版本的Python内置库。这些将位于某个目录中,例如/usr/lib/python3/dist-packages。同时,还需要将pip安装与二进制文件一起包含,因为没有pip,您无法安装第三方库。

  2. "环境"。同样,“环境”这个术语使用得非常宽泛,没有人知道它从哪里开始或结束,或者正在引用哪种特定的环境。一旦开始构建项目,你首先要做的事情之一就是使用pip下载和安装第三方库。这些被安装到本地的site_packages目录中,该目录具有其预期的规范位置,但只要正确引用,可以放在任何地方,以便“Python”可以找到它。 site_packages目录本质上就是您的“环境”。

需求:使用多个“Python”及其各自的多个“环境”

这就是它的实现方式。

哪个“Python”版本?

您将开始使用多个“Python”。您将拥有Python 3.7、Python 3.10等,它们可能会增加。它们可以被重复使用,但您需要安装它们所有,这需要不同的位置,并告知项目中的工具您正在使用此项目的路径。

哪个“环境”版本?

即使对于一个特定的Python版本,也可能会有多个项目使用相同的“Python”,但使用单独的、不同的“环境”。一个Python 3.10项目可能会使用一个版本的requests库,另一个3.10项目可能需要不同版本的requests库,您不希望其中一个的安装覆盖另一个的安装:您需要为每个项目分别设置site_packages目录。

工具:管理“Python”的工具与管理“环境”的工具

这是我失去一些准确性的地方。我不熟悉所有工具,它们都有“env”在它们的名称中。聪明,对吧?我们可以理解如果它们的名称中都有“py”,那似乎是不可避免的。但是,如果一个工具管理Python安装而不是环境,为什么它被称为pyenv呢?

“Python”管理工具

老实说,我以前没有使用过pyenv。我只是使用操作系统软件包管理来管理Python安装,或者我只是坚持使用一个版本的Python。然而最近出现了问题,因为系统可能依赖于特定位置的特定版本的Python,所以这次我想使用pyenv

也许pyenv在某种程度上也管理“环境”,但我使用它来安装多个“Python”。当我使用pyenv(如何执行超出了本答案的范围)时,我想要安装特定版本的Python及其内置功能,并且还要安装相关的pip

这只需要进行少量操作,因为我只在需要一个我还没有的 Python 版本时才这样做。当我使用 pyenv 安装 Python 3.7.9 并激活它后,我现在可以启动该 Python 版本并使用它。我可以在命令行上引用它,如 python。我可以说 python -m pip install ...

但是我还没有在我的环境中安装任何库。因为我将在多个项目中使用 Python 3.7.9,每个项目都有不同的环境...

“环境”管理工具
这就是环境管理工具发挥作用的地方。本问题涉及到virtualenvvirtualenvwrapper,但它们现在已经有点过时了,本回答重点介绍这些工具的区别和原因。我现在使用venv创建激活环境。一旦我选择(激活)了特定的python,我就使用该Python创建一个“环境”,该环境也可以被激活。一旦我激活了该环境,无论何时使用python,它都将使用我创建环境时使用的Python版本和(pip),并且无论何时我说pip install,我都将使用那个特定的site_packages来安装第三方库。

项目工作流程

现在你可以设置多个项目使用同一个Python,而且可以从多个Pythons中进行选择。

  1. 使用您的“Python管理”工具pyenv创建和/或激活所需的Python版本。
  2. 使用特定激活的Python,使用您的“环境管理”工具venv(或virtualenvwrapper)创建和/或激活项目的环境。
  3. 现在每次运行Python时都是相同的版本,并且所有pip安装仅驻留在此本地项目中,不会影响其他项目。
  4. 您可以随时关闭它(停用)并激活另一个。
  5. 您可以同时在多个项目上拥有多个shell会话。每个Python和每个环境都在该shell会话中使用$PATH和其他Linux环境变量进行激活和引用。您的shell提示通常显示名称,以便您能够查看当前激活的特定环境。

更多信息

如果您想了解更多关于venv的信息,特别是(如果我说错了,请纠正我)它似乎是当前Python版本的事实标准,您可以在深入解释venv中找到相关内容。

1
虚拟环境的一个重要特点是它们是可丢弃的。如果您尝试使用不同的依赖项并随时安装它们,很快就会陷入一种情况,您不知道何时安装了什么或如何重新创建或记录该情况。能够清除所有内容并重新开始使其可重复和可再现。 - tripleee
1
这也对整个系统健康产生了影响;在以前不好的日子里,你会在需要它们时系统范围内随机安装随机库的不同版本,但并不知道你已经安装了什么或新项目或旧项目的重新部署可能会有什么影响。为每个项目或任务隔离依赖项可以消除积累系统垃圾的趋势。 - tripleee
我可能不太确定具体的工具,但我试图超越这一点,通过指出你需要一个Python版本和一个环境来提供锚定。这应该为程序员提供概念,以便他们将不同的工具混淆挂在上面。程序员可以开始依赖于哪个是选择Python的工具,哪个是设置环境的工具,以及如果发生重叠时它们在哪里重叠。我建议您查看venv(python -m venv --prompt name .venv),因为我认为它比pyenv-virtualenv更年轻(现在也更推荐)。 - NeilG
1
实际上,基本的pyenv只用于管理不同的Python版本及其标准库。您可以为您使用pyenv选择的Python版本在整个系统范围内安装库,但您可能不希望这样做,因此pyenv-virtualenv添加了一个功能,用于创建单独的虚拟环境,可以用于不同的项目。对于我早期评论的不够精确表示抱歉。 - tripleee
1
@NeilG 我同意你的反对意见:它非常简单,“pyenv”的命名不太好。它应该被称为“pyversions”。除此之外,尽管我确实是一个“新手”,但我并没有从其他答案中感到太多困惑,特别是关于pyenv。 - mike rodent
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接