如何在 Mac 上使用 pyenv 运行多个 Python 版本

如果您需要运行一个项目,而该项目使用的 Python 版本在 macOS 上没有安装,请尝试 pyenv。
219 位读者喜欢这篇文章。
Searching for code

Opensource.com

即使对于经验丰富的开发人员来说,管理本地 Python 开发环境仍然是一个挑战。虽然有充分记录的 包管理策略,但还需要一个步骤来确保您在需要时运行所需的 Python 版本。

为什么 Python 版本很重要?

乍一看这是一个奇怪的概念,但编程语言像任何其他软件一样会发生变化。它们像您喜欢的任何 API 和任何其他软件一样,都有错误、修复和更新。同样,不同的版本由一个三位数字的数字标识,称为 语义版本

多年来,Python 2 是常用的主要编程语言版本。在 2020 年 1 月,Python 2 达到了生命周期结束,从那时起,只有 Python 3 将得到该语言核心维护者的支持。Python 3 正在稳步发展,并定期发布新的更新。这使得我定期获取这些更新变得很重要。

最近,我尝试在 macOS 上运行一个依赖于 Python 3.5.9 的项目,而我的系统上没有安装这个版本。可能看起来很合乎逻辑地认为 Python 包管理器 pip 可以安装它*,但事实并非如此

$ pip install python3.5.9
Collecting python3.5.9
  ERROR: Could not find a version that satisfies the requirement python3.5.9 (from versions: none)
ERROR: No matching distribution found for python3.5.9

或者,我可以从官方 Python 网站下载该版本,但如何在我的 Mac 上与我现有的 Python 版本一起运行它呢?每次运行解释器时都指定要使用的 Python 版本(例如 python3.7 或 python3.5)似乎充其量是容易出错的。肯定有更好的方法。

(关于上面的一点说明:我知道这对经验丰富的 Python 开发者来说毫无意义,但当时对我来说是有意义的。我愿意愉快地讨论为什么我仍然认为它应该如此。)

安装和设置 pyenv

值得庆幸的是,pyenv 的存在是为了解决这一系列复杂性。首先,我需要安装 pyenv。我可以自己从 源代码 克隆和编译它,但我更喜欢通过 Homebrew 包管理器来管理这样的包

$ brew install pyenv

为了通过 pyenv 使用 Python 版本,了解 shell 的 PATH 变量至关重要。PATH 决定了 shell 通过命令名称搜索文件的位置。您必须确保 shell 将找到由 pyenv 运行的 Python 版本,而不是默认安装的版本(通常称为系统版本)。如果您不更改路径,这是结果

$ which python
/usr/bin/python

那是系统版本的 Python。

要正确设置 pyenv,您可以在 Bash 或 zsh 中运行以下命令

$ PATH=$(pyenv root)/shims:$PATH

现在,如果您检查 Python 的版本,您会看到它是 pyenv 管理的版本

$ which python
/Users/my_username/.pyenv/shims/python

该 export 语句 (PATH=) 将仅对此 shell 实例有效,因此要使其成为永久更改,您需要将其添加到您的 dotfiles 中。由于 zsh 是 macOS 的官方默认 shell,我将重点关注它。将相同的语法附加到 ~/.zshrc 文件

$ echo 'PATH=$(pyenv root)/shims:$PATH' >> ~/.zshrc

现在,每次我们在 zsh 中运行命令时,它都会使用 pyenv 版本的 Python。请注意,我在 echo 中使用了单引号,因此它不会评估和扩展命令。

.zshrc 文件仅管理 zsh 实例,因此请务必检查您的 shell 是什么并编辑关联的 dotfiles。如果您需要再次检查您的默认 shell 是什么,您可以运行 echo $SHELL。如果它是 zsh,请使用上面的命令。如果您使用 Bash,请将 ~/.zshrc 更改为 ~/.bashrc。如果您想了解更多信息,可以深入研究 pyenv 的 README 中的 路径设置

使用 pyenv 管理 Python 版本

现在 pyenv 处于控制之下,我们可以看到它只有系统 Python 可用

$ pyenv versions
system

如上所述,您绝对不想使用此版本(阅读更多关于原因的信息)。现在 pyenv 已正确设置,我希望它拥有几个我经常使用的不同 Python 版本。

有一种方法可以查看 pyenv 可以访问的所有不同存储库中的所有可用 Python 版本,方法是运行 pyenv install --list。这是一个很长且令人眼花缭乱的列表,将来可能有助于查看。目前,我坚持使用 Python 下载页面 上找到的每个点版本(3.5.x 或 3.6.x,其中 x 是最新版本)的最新版本。考虑到这一点,我将安装 3.5.9 和 3.8.0

$ pyenv install 3.5.9
$ pyenv install 3.8.0

这将需要一段时间,所以去喝杯茶(或阅读上面的链接之一)。有趣的是,输出会逐步显示该 Python 版本的下载和构建过程。例如,输出显示该文件直接来自 Python.org

安装完成后,您可以设置您的默认值。我喜欢走在前沿,所以我将我的全局默认 Python 版本设置为最新版本

$ pyenv global 3.8.0

并且该版本立即在我的 shell 中设置。为了确认

$ python -V 
Python 3.8.0

我要运行的项目仅适用于 Python 3.5,所以我将在本地设置版本并确认它正在使用中

$ pyenv local 3.5.9
$ python -V
Python 3.5.9

因为我对 pyenv 使用了 local 选项,所以它在我的当前目录中添加了一个文件来跟踪该信息。

$ cat .python-version
3.5.9

现在,我终于可以为我想要的项目设置虚拟环境,并确保我正在运行正确的 Python 版本。

$ python -m venv venv
$ source ./venv/bin/activate
(venv) $ which python
/Users/mbbroberg/Develop/my_project/venv/bin/python

要了解更多信息,请查看有关 在 Mac 上管理虚拟环境 的本教程。

总结

默认情况下,运行多个 Python 版本可能是一个挑战。我发现从 pyenv 开始可以确保我拥有运行所需的 Python 版本。

您是否有其他初级或中级 Python 问题?请留言,我们将考虑在以后的文章中解答。

接下来阅读
标签
I'm happiest at a microphone
Matt 曾是 EMC 存储专家、VMware vExpert 和其他专有技术的爱好者。他现在专注于开源和 DevRel 采用。

贡献者

3 条评论

您好 Matthew。好文章,也是最近的文章。

我有一些问题。我也在 Catalina/Zsh 上使用 pyenv,但不使用 Conda。您在使用 Conda 吗?我不想使用 Conda,因为它从不使用最新版本的 RStudio,但我可能无论如何都必须使用它,以便在同一个笔记本中使用 Python 和 R,即使用 Reticulate 或其他东西。您认为除了这一点之外,使用 Conda 还有什么优势吗?

无论如何,我的主要问题是这个。我正在阅读一个教程,该教程使用以下示例命令设置虚拟环境。

$ pyenv virtualenv 3.8.0 bleeding_edge_project
$ pyenv virtualenv 3.7.0 tensorflow_project

然后可以使其全局化并在任何时候切换。
$ pyenv global 3.8.0 bleeding_edge_project
切换
$ pyenv global 3.7.0 tensorflow_project

这些环境位于 ~/.pyenv/versions... 目录中。

但我们也可以使用 mkproject 或 mkvirtualenv 来创建虚拟环境和相应的项目文件夹,这些文件夹位于 ~/.ve 和 ~/workspace。

有什么区别?我只需要 pyenv 吗?我知道如果我们使用 mkproject,我们可以使用 workon 切换环境。我知道 pyenv 的目的是允许我们控制我们正在使用的 python 版本。那么我应该如何将 workon 功能与 pyenv 功能结合使用呢?

感谢这篇内容丰富的文章。

Ben

如果您使用 /bin/bash,请使用 .bash_profile 文件而不是 .bashrc,例如

echo 'PATH=$(pyenv root)/shims:$PATH' >> ~/.bash_profile

只有这样对我才有效。

嘿 Matthew,这里关于 pyenv 的两篇文章都非常翔实且有帮助。但是当运行“pyenv install python 3.8.2”时,我遇到了一个问题

configure: error: cannot compute sizeof (size_t)

这是一个已知问题吗?我正在运行 macOS Catalina,10.15.5,以及最新的 XCode,11.5 (16139)。

Creative Commons License本作品根据 知识共享许可协议 署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.