引言
你是否曾希望参与一个支持多个 Python 版本的项目,但又不知道如何轻松地测试所有这些版本?你是否对 Python 的最新版本感到好奇?或许你想尝试这些新功能,但又不想冒险破坏你的开发环境。幸运的是,如果你使用 pyenv,管理多个 Python 版本并不复杂。
本文将向你展示如何高效地在项目上工作,同时减少因尝试使用正确版本的 Python 而产生的困扰。
通过本文,你将学会:
- 安装多个 Python 版本
- 安装 Python 的最新开发版
- 在已安装的版本间切换
- 与 pyenv 一起使用虚拟环境
- 自动激活不同的 Python 版本和虚拟环境
pyenv 命令
pyenv 提供了许多命令。您可以使用以下命令查看所有可用命令的完整列表:
$ pyenv commands
activate
commands
completions
deactivate
...
virtualenvs
whence
which
这将输出所有命令名称。每个命令都有一个 --help 标志,可以为您提供更详细的信息。例如,如果您想查看有关 shims 命令的更多信息,您可以运行以下命令:
$ pyenv shims --help
Usage: pyenv shims [--short]
List existing pyenv shims
指定您的 Python 版本
pyenv 中更令人困惑的部分之一是 python 命令到底是如何解析的以及可以使用哪些命令来修改它。正如命令中提到的,有 3 种方法可以修改您正在使用的 python 版本。那么所有这些命令如何相互交互呢?解析顺序看起来有点像这样:
这个金字塔应该从上到下阅读。 pyenv 可以找到的第一个选项是它将使用的选项。让我们看一个简单的例子:
$ pyenv versions
* system (set by /home/realpython/.pyenv/version)
2.7.15
3.6.8
3.8-dev
在这里,您的系统 Python 正在使用,如 * 所示。要执行下一个最全局的设置,您可以使用 global:
$ pyenv global 3.6.8
$ pyenv versions
system
2.7.15
* 3.6.8 (set by /home/realpython/.pyenv/version)
3.8-dev
你可以看到现在 pyenv 希望使用 3.6.8 作为我们的 Python 版本。它甚至指示它找到的文件的位置。该文件确实存在,您可以列出其内容:
$ cat ~/.pyenv/version
3.6.8
现在,让我们使用 local 创建一个 .python-version 文件:
$ pyenv local 2.7.15
$ pyenv versions
system
* 2.7.15 (set by /home/realpython/.python-version)
3.6.8
3.8-dev
$ ls -a
. .. .python-version
$ cat .python-version
2.7.15
在这里,pyenv 再次表明它将如何解析我们的 python 命令。这次它来自~/.python-version。请注意,搜索 .python-version 是递归的:
$ mkdir subdirectory
$ cd subdirectory
$ ls -la # Notice no .python-version file
. ..
$ pyenv versions
system
* 2.7.15 (set by /home/realpython/.python-version)
3.6.8
3.8-dev
即使子目录中没有 .python-version,版本仍设置为 2.7.15,因为 .python-version 存在于父目录中。
最后,您可以使用 shell 设置 Python 版本:
$ pyenv shell 3.8-dev
$ pyenv versions
system
2.7.15
3.6.8
* 3.8-dev (set by PYENV_VERSION environment variable)
这一切所做的就是设置 $PYENV_VERSION 环境变量:
$ echo $PYENV_VERSION
3.8-dev
虚拟环境与 pyenv
虚拟环境在管理 Python 安装和应用程序中扮演着重要角色。虚拟环境与 pyenv 的结合堪称完美。pyenv 拥有一个名为 pyenv-virtualenv 的插件,它让处理多个 Python 版本和多个虚拟环境变得轻而易举。如果你对 pyenv、pyenv-virtualenv 以及 virtualenv 或 venv 等工具之间的区别感到困惑,不必担心,你并不孤单。
以下是你需要了解的信息:
- pyenv 负责管理 Python 的多个版本。
- virtualenv/venv 负责管理特定 Python 版本的虚拟环境。
- pyenv-virtualenv 负责管理跨不同 Python 版本的虚拟环境。 如果你习惯使用 virtualenv 或 venv,也不用担心:pyenv 能够与它们很好地协作。实际上,如果你愿意,可以继续沿用你现有的工作流程,尽管我认为在需要在不同环境之间切换且这些环境要求不同 Python 版本时,pyenv-virtualenv 能提供更流畅的体验。
好消息是,由于你使用了 pyenv-installer 脚本来安装 pyenv,你已经安装好了 pyenv-virtualenv,随时可以使用。
创建虚拟环境
创建虚拟环境只需一条命令:
$ pyenv virtualenv <python_version> <environment_name>
严格来说,<python_version>
参数是可选的,但我建议你总是明确指定它,以确保你知道自己正在使用的 Python 版本。
<environment_name>
是你用来区分不同环境的名称。一个好习惯是将环境名称设置为与项目名称相同。例如,如果你正在开发名为 myproject 的项目,并且打算使用 Python 3.6.8 版本进行开发,你应该执行如下命令:
$ pyenv virtualenv 3.6.8 myproject
输出中包含了一些额外安装的 Python 包的信息,包括 wheel、pip 和 setuptools。这完全是为了方便,为你的每个虚拟环境配置了一个功能更完善的环境。
激活你的版本 既然你已经创建了虚拟环境,接下来的步骤就是激活它。通常情况下,你应该通过执行以下命令来激活你的虚拟环境:
$ pyenv local myproject
你之前已经接触过 pyenv local
命令,但这次不同,你不是指定一个 Python 版本,而是指定一个环境。这样做会在你当前的工作目录下创建一个 .python-version
文件。由于你之前在环境中执行了 eval "$(pyenv virtualenv-init -)"
命令,所以环境将自动激活。
你可以通过执行以下命令来确认环境是否已激活:
$ pyenv which python
/home/realpython/.pyenv/versions/myproject/bin/python
你可以看到,一个名为 myproject 的新版本已经被创建,并且 python 执行路径已经指向了这个版本。如果你查看这个环境提供的任何可执行文件,你会发现它们的情况都是相同的。以 pip 为例:
$ pyenv which pip
/home/realpython/.pyenv/versions/myproject/bin/pip
如果您没有配置 eval "$(pyenv virtualenv-init -)" 在 shell 中运行,您可以使用以下命令手动激活/停用您的 Python 版本:
$ pyenv activate <environment_name>
$ pyenv deactivate
这就是当你进入或离开包含 .python-version
文件的目录时,pyenv-virtualenv
所做的事情。
高效管理多个环境
将你学到的知识综合起来,你就可以高效地管理多个环境了。我们假设你已经安装了如下几个版本:
$ pyenv versions
* system (set by /home/realpython/.pyenv/version)
2.7.15
3.6.8
3.8-dev
目前,你打算着手两个命名恰当的项目:
- project1 兼容 Python 2.7 和 3.6 版本。
- project2 兼容 Python 3.6 版本,并正在测试 3.8-dev 版本。
从 pyenv 版本输出中可以看到 * 标记,表示你当前默认使用的是系统 Python。首先,你需要为第一个项目创建一个虚拟环境:
$ cd project1/
$ pyenv which python
/usr/bin/python
$ pyenv virtualenv 3.6.8 project1
...
$ pyenv local project1
$ python -V
/home/realpython/.pyenv/versions/project1/bin/python
最后,请注意,当您 cd 退出该目录时,您默认返回到系统 Python:
$ cd $HOME
$ pyenv which python
/usr/bin/python
您可以按照上述步骤,为project2创建一个虚拟环境:
$ cd project2/
$ pyenv which python
/usr/bin/python
$ pyenv virtualenv 3.8-dev project2
...
$ pyenv local 3.8-dev
$ pyenv which python
/home/realpython/.pyenv/versions/3.8-dev/bin/python
这些是您的项目的一次性步骤。现在,当您在项目之间切换时,您的环境将自动激活:
$ cd project2/
$ python -V
Python 3.8.0a0
$ cd ../project1
$ python -V
Python 3.6.8
无需再手动激活环境:你可以轻松切换不同的项目,pyenv 会负责自动激活相应的 Python 版本和虚拟环境。
同时激活多个版本
正如上文示例中提到的,project2 利用了 Python 3.8 中的实验性功能。假设你希望确保你的代码也能在 Python 3.6 上正常运行。如果你尝试执行 python3.6,你会遇到以下情况:
$ cd project2/
$ python3.6 -V
pyenv: python3.6: command not found
The `python3.6' command exists in these Python versions:
3.6.8
3.6.8/envs/project1
project1
pyenv 通知您,虽然 Python 3.6 在当前活动环境中不可用,但在其他环境中可用。 pyenv 为您提供了一种使用熟悉的命令同时激活多个环境的方法:
$ pyenv local project2 3.6.8
这向 pyenv 表明您希望使用虚拟环境 project2 作为第一个选项。因此,如果一个命令(例如 python)可以在两个环境中解析,则它将选择 3.6.8 之前的project2。
$ python3.6 -V
Python 3.6.8
在这种情况下,pyenv 会尝试定位 python3.6
命令,并且因为它在一个已激活的环境中找到了这个命令,所以允许执行。这对于需要多个 Python 版本在 PATH 环境变量中可用以执行操作的工具(如 tox)来说极为有用。
假设在上述例子中,你发现了与你的库的兼容性问题,并希望进行本地测试。测试需要你安装所有依赖项。你应该按照创建新环境的步骤进行:
$ pyenv virtualenv 3.6.8 project2-tmp
$ pyenv local project2-tmp
一旦您对本地测试感到满意,您可以轻松切换回默认环境:
$ pyenv local project2 3.6.8
总结
你现在能够更加便捷地参与支持多种环境的项目。同时,你也可以无忧地测试最新版本的 Python,不必担心破坏你的开发环境,这都要归功于一个强大的工具:pyenv。
你已经了解到 pyenv 如何助你一臂之力:
- 安装多个版本的 Python
- 在这些版本间轻松切换
- 利用 pyenv 管理虚拟环境
- 自动激活不同的 Python 版本和虚拟环境 如果你有任何疑问,无论是在评论区域还是 Twitter 上,都可以随时提出。另外,pyenv 的官方文档也是一个极好的学习资源。