一文快速入门 Pyenv:Python 多版本自由切换 – wiki基地


一文快速入门 Pyenv:Python 多版本自由切换

作为 Python 开发者,你是否曾遇到这样的困境?

一个老项目依赖 Python 3.6,而你的新项目需要 Python 3.10 的新特性;你在尝试一个第三方库,它只声明支持 Python 3.8+;或者你只是想测试一下你的代码在不同 Python 版本下的兼容性。更令人头疼的是,你的操作系统自带了一个 Python 版本,你安装的软件可能依赖它,你却不小心升级或改动了它,导致系统某些功能失效。

在没有合适的工具之前,管理这些不同的 Python 版本简直是一场噩梦。手动安装、配置 PATH 环境变量、处理不同版本库的冲突……这些繁琐的操作不仅效率低下,还极易出错,甚至可能破坏系统的稳定性。

幸运的是,有这样一款工具,它能够优雅地为你解决这些问题,让你在不同 Python 版本之间自由穿梭,丝滑切换,它就是 Pyenv

什么是 Pyenv?为什么你需要它?

简单来说,Pyenv 是一个简单的 Python 版本管理工具。它允许你在同一台机器上安装和管理多个 Python 版本(包括 CPython、Jython、PyPy、Anaconda 等发行版),并且可以轻松地在全局、用户级别或项目级别切换使用不同的 Python 版本。

Pyenv 的核心理念是不干扰系统原生的 Python。它通过巧妙的机制(shims)来拦截你执行 pythonpip 等命令的调用,然后根据你配置的环境变量或当前目录下的设置,将这些命令重定向到你指定版本的 Python 可执行文件。

Pyenv 解决了以下痛点:

  1. 避免与系统 Python 冲突: Pyenv 安装的 Python 版本是独立的,不会影响操作系统自带的 Python,保证了系统的稳定。
  2. 项目依赖不同版本: 不同的项目可以使用不同的 Python 版本,互不干扰,解决了版本兼容性问题。
  3. 轻松测试兼容性: 开发者可以方便地在多个 Python 版本下测试自己的代码,确保其在不同环境下的健壮性。
  4. 干净的环境: Pyenv 使得安装、卸载和切换 Python 版本变得非常简单和干净。
  5. 支持多种 Python 发行版: 不仅限于官方 CPython,Pyenv 还支持安装 Anaconda、Miniconda、PyPy、Jython 等。

需要注意的是,Pyenv 主要管理的是 Python 解释器本身的版本。它通常与虚拟环境工具(如 Python 内置的 venv 或第三方库 virtualenv)结合使用。虚拟环境工具管理的是特定 Python 版本下的第三方库依赖。Pyenv 负责提供不同版本的 Python 解释器,而虚拟环境则负责在这个解释器下隔离项目所需的库,两者相辅相成,提供了最完整的 Python 开发环境管理方案。后续我们将重点介绍 Pyenv 如何与虚拟环境工具配合使用(特别是 pyenv-virtualenv 插件)。

Pyenv 的安装:迈出第一步

安装 Pyenv 是使用它的第一步。Pyenv 的安装通常涉及到克隆其 Git 仓库并进行一些 shell 环境配置。Pyenv 的作者提供了一个方便的安装器脚本 pyenv-installer,推荐新手使用,因为它会自动安装 Pyenv、所需的插件以及进行基本的环境配置。

重要前提:构建依赖

因为 Pyenv 安装 Python 版本时,通常是从源代码进行编译安装,所以你需要确保你的系统安装了必要的构建工具和库。这通常是新手最容易遇到的问题。

  • macOS:
    • 安装 Xcode Command Line Tools: xcode-select --install
    • 使用 Homebrew 安装必要的库: brew install [email protected] readline zlib bzip2 xz (注意 openssl 的版本,不同 macOS 版本或 Python 版本可能需要不同的 openssl 版本,openssl@3 也是常见的,可以根据 Pyenv 安装过程中的提示或错误信息调整)。
  • Debian/Ubuntu Linux:
    • sudo apt update
    • sudo apt install build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
  • Fedora/CentOS/RHEL Linux:
    • sudo yum update (或 dnf update)
    • sudo yum install @development zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel libffi-devel xz-devel (或 dnf groupinstall "Development Tools" && dnf install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel libffi-devel xz-devel)

方法一:使用 pyenv-installer (推荐新手)

这是最简单快捷的方式。打开终端,执行以下命令:

bash
curl https://pyenv.run | bash

这个脚本会自动:
1. 克隆 Pyenv 仓库到 ~/.pyenv
2. 克隆 pyenv-doctorpyenv-installerpyenv-updatepyenv-virtualenv 插件到 ~/.pyenv/plugins
3. 在你的 shell 配置文件(如 ~/.bashrc, ~/.zshrc, ~/.profile)中添加必要的 Pyenv 配置行。

安装脚本执行完毕后,它会提示你关闭并重新打开终端,或者手动 source 一下你的 shell 配置文件,使配置生效。例如:

“`bash
source ~/.bashrc # 如果你使用的是 Bash

source ~/.zshrc # 如果你使用的是 Zsh
“`

验证安装:

重新打开终端或 source 配置文件后,执行以下命令:

bash
pyenv --version

如果输出了 Pyenv 的版本号,说明 Pyenv 本身安装成功。

接着,验证 shell 集成是否成功:

bash
type python

如果输出类似 python is a functionpython is hashed (/home/youruser/.pyenv/shims/python),说明 Pyenv 的 shims 机制已经正确加载,可以拦截 python 命令了。如果输出的是 /usr/bin/python 或其他系统路径,说明 shell 配置没有生效,你需要仔细检查 .bashrc/.zshrc 等文件中的 Pyenv 配置行是否正确添加,并确保文件被 shell 加载。

方法二:手动安装 (Git Checkout)

如果你不想使用安装器,或者想更精细地控制安装过程,可以手动安装:

  1. 克隆仓库:
    bash
    git clone https://github.com/pyenv/pyenv.git ~/.pyenv
  2. 配置环境变量: 将 Pyenv 的 bin 目录添加到你的 PATH 环境变量中,并将 Pyenv 初始化脚本添加到你的 shell 配置文件中。
    打开你的 shell 配置文件 (如 ~/.bashrc~/.zshrc),添加以下内容:

    “`bash

    Pyenv 配置

    export PYENV_ROOT=”$HOME/.pyenv”
    export PATH=”$PYENV_ROOT/bin:$PATH”
    eval “$(pyenv init –path)”

    可选:添加 pyenv init 到 shell 以启用 shims 和自动补全

    eval “$(pyenv init -)” # 如果你使用的是较新的 Pyenv 版本且shell支持function shims,推荐使用 –path,否则使用 –

    为了兼容性和简便,大多数文档仍然推荐 eval “$(pyenv init -)”

    Pyenv 文档推荐 eval “$(pyenv init –path)” 和 eval “$(pyenv init -)” 分开写以确保正确性:

    export PYENV_ROOT=”$HOME/.pyenv”

    command -v pyenv >/dev/null || export PATH=”$PYENV_ROOT/bin:$PATH”

    eval “$(pyenv init -)”

    eval “$(pyenv virtualenv-init -)” # 如果你安装了 pyenv-virtualenv 插件

    ``
    **解释:**
    *
    export PYENV_ROOT=”$HOME/.pyenv”:定义 Pyenv 的安装根目录。
    *
    export PATH=”$PYENV_ROOT/bin:$PATH”:将 Pyenv 的bin目录(包含pyenv可执行文件)添加到 PATH 的最前面,这样你就可以直接执行pyenv命令。
    *
    eval “$(pyenv init –path)”:这是 Pyenv 核心配置的一部分。它会修改你的 PATH 环境变量,将 Pyenv 的 shims 目录 ($PYENV_ROOT/shims) 添加到 PATH 的最前面。**Shims** 是 Pyenv 实现版本切换的关键:它们是与python,pip等同名的可执行文件,当你执行这些命令时,shell 会先找到 shims 目录下的文件并执行它,然后 shims 会根据你的 Pyenv 配置找到正确的 Python 版本并执行对应的命令。–path参数是较新的推荐方式,只修改 PATH。
    *
    eval “$(pyenv init -)”:这个命令会输出一些 shell 代码,通常用于设置 shell 函数和自动补全。如果你不使用–path方式,这个命令也会修改 PATH。
    *
    eval “$(pyenv virtualenv-init -)”:如果你手动安装了pyenv-virtualenv` 插件,也需要将其初始化添加到 shell 配置。

  3. 重新加载 shell 配置: 关闭并重新打开终端,或执行 source ~/.bashrc (或 ~/.zshrc)。

  4. 验证安装: 同上,执行 pyenv --versiontype python

手动安装插件 (如果需要,如 pyenv-virtualenv):

bash
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv

然后确保在 shell 配置中添加了 eval "$(pyenv virtualenv-init -)" 并重新加载配置。

基本使用:安装与切换 Python 版本

安装好 Pyenv 并配置好 shell 环境后,就可以开始安装和管理不同的 Python 版本了。

  1. 查看可安装的 Python 版本:

    “`bash
    pyenv install –list

    或者简写

    pyenv install -l
    ``
    这个命令会列出所有可以通过 Pyenv 安装的 Python 版本,包括 CPython、Anaconda、Miniconda、PyPy 等。列表很长,你可以通过管道和
    grep` 来查找特定版本,例如:

    bash
    pyenv install -l | grep "3.9"

  2. 安装一个 Python 版本:

    选择你想安装的版本号(例如 3.9.18),执行安装命令:

    bash
    pyenv install 3.9.18

    Pyenv 会从 Python 官方网站下载源代码包,然后在你的本地进行编译安装。这个过程可能需要一些时间,取决于你的网速和电脑性能。请耐心等待,并留意安装过程中是否有错误提示(通常是缺少构建依赖)。

    你可以安装多个不同版本的 Python:

    bash
    pyenv install 3.11.7
    pyenv install 3.12.3

  3. 查看已安装的 Python 版本:

    bash
    pyenv versions

    这个命令会列出所有已通过 Pyenv 安装在你系统中的 Python 版本。输出示例:

    system
    * 3.9.18 (set by /home/youruser/.pyenv/version)
    3.11.7
    3.12.3

    * system 表示你系统自带的 Python 版本。
    * 带有 * 符号的版本表示当前激活的 Python 版本。括号中的文字说明了这个版本是如何被激活的(例如,通过 .pyenv/version 文件设置的全局版本)。

  4. 设置 Python 版本:

    Pyenv 提供了三种设置 Python 版本的方式,它们有不同的作用域和优先级:

    • pyenv global <version>:设置全局默认版本
      这个命令会将指定的 Python 版本设置为你的系统默认版本,除非被 localshell 设置覆盖。它会在 $PYENV_ROOT 目录下创建一个名为 version 的文件,并将版本号写入其中。
      例如:
      bash
      pyenv global 3.11.7

      现在,在任何没有 .python-version 文件的目录,或者没有使用 pyenv shell 指定版本的情况下,你执行 python 命令都会调用 Pyenv 管理的 3.11.7 版本。

    • pyenv local <version>:设置项目特定版本
      在你的项目根目录下执行这个命令,Pyenv 会在该目录下创建一个名为 .python-version 的文件,并将指定的 Python 版本号写入其中。当你进入这个目录或其子目录时,Pyenv 会自动激活这个版本。这是在项目开发中最常用的方式,确保项目的依赖和运行环境与团队成员保持一致。
      例如,在一个名为 my-project 的目录中:
      bash
      cd my-project
      pyenv local 3.9.18

      现在,只要你在 my-project 目录及其子目录中,python 命令就会指向 Pyenv 管理的 3.9.18 版本。当你切换到其他目录时,如果其他目录没有 .python-version 文件,则会 fallback 到全局或系统版本。

    • pyenv shell <version>:设置当前 shell 会话版本
      这个命令只对当前终端会话有效。它会在当前 shell 进程的环境变量中设置一个临时版本。优先级最高,会覆盖 localglobal 设置。当你关闭当前终端会话或打开新的终端会话时,这个设置就会失效。常用于临时切换版本进行测试。
      例如:
      bash
      pyenv shell 3.12.3

      现在,在当前终端窗口中,无论全局或本地设置是什么,python 都将使用 3.12.3 版本。

    优先级总结: shell > local > global > system

  5. 查看当前激活的 Python 版本:

    bash
    pyenv version

    这个命令会输出当前激活的 Python 版本及其激活方式(来自 global, local, shell 设置或 system)。

  6. 查找当前激活 Python 解释器的实际路径:

    bash
    pyenv which python

    这个命令会显示当前 Pyenv 激活的 python 可执行文件的真实路径,通常在 ~/.pyenv/versions/<version>/bin/python 下。这有助于理解 Pyenv 的 shims 是如何工作的。

  7. 更新 shims:

    bash
    pyenv rehash

    Pyenv 通过 shims 目录来管理可执行文件(如 python, pip)。每当你安装一个新的 Python 版本、安装一个包含可执行文件(例如通过 pipx 安装的命令行工具)的包时,Pyenv 需要更新 shims 目录,创建指向这些新可执行文件的符号链接。虽然新版本的 Pyenv 在安装 Python 后会自动执行 rehash,但在某些情况下(例如手动安装插件或遇到奇怪的路径问题),你可能需要手动执行它。

Pyenv 与虚拟环境:最佳实践

如前所述,Pyenv 管理 Python 解释器版本,而虚拟环境管理特定解释器下的第三方库。两者结合使用是 Python 开发的最佳实践。最方便的方式是使用 pyenv-virtualenv 插件。

安装 pyenv-virtualenv 插件:

如果你使用了 pyenv-installer,这个插件应该已经自动安装了。你可以通过检查 ~/.pyenv/plugins/ 目录是否存在 pyenv-virtualenv 子目录来确认。

如果不存在,或者你手动安装的 Pyenv,可以通过 Git 克隆安装:

bash
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv

然后,确保你的 shell 配置文件中包含了 eval "$(pyenv virtualenv-init -)" 并重新加载配置。

使用 pyenv-virtualenv 创建虚拟环境:

该插件允许你在一个特定的 Pyenv 管理的 Python 版本基础上创建虚拟环境。

命令格式:pyenv virtualenv <python_version> <env_name>

其中:
* <python_version> 是你已经通过 pyenv install 安装的 Python 版本号。
* <env_name> 是你给这个虚拟环境起的名字,通常是你的项目名加上版本号或其他描述性信息(例如 my-project-3.9)。

示例:
假设你已经安装了 Python 3.9.18,现在想基于它创建一个名为 my-app-env 的虚拟环境:

bash
pyenv virtualenv 3.9.18 my-app-env

这个命令会创建一个新的虚拟环境,其解释器是 Pyenv 管理的 3.9.18 版本,并将这个环境保存在 ~/.pyenv/versions/my-app-env 目录下。

查看所有虚拟环境:

使用 pyenv versions 命令也可以看到通过 pyenv-virtualenv 创建的虚拟环境,它们会显示为 <python_version>/envs/<env_name> 或直接显示 <env_name>,取决于 Pyenv 的版本和配置。

“`bash
pyenv versions

输出示例:

system

* 3.9.18 (set by /home/youruser/.python-version)

3.11.7

3.12.3

3.9.18/envs/my-app-env

my-app-env

``
注意,虚拟环境的名称
my-app-env` 也会出现在列表中,这表示你可以像切换普通 Python 版本一样切换到这个虚拟环境。

激活虚拟环境:

激活虚拟环境的最常见和推荐方式是结合 pyenv localpyenv shell 命令。

  • 项目目录中自动激活:
    在你的项目根目录下,使用 pyenv local 命令设置虚拟环境:
    bash
    cd /path/to/my-app
    pyenv local my-app-env

    这会在 /path/to/my-app 目录下创建一个 .python-version 文件,内容就是 my-app-env。当你进入 /path/to/my-app 目录时,Pyenv 会自动激活 my-app-env 虚拟环境。此时,你的 python 命令和 pip 命令都会指向 my-app-env 虚拟环境内的可执行文件。

  • 临时激活:
    在当前 shell 会话中临时激活虚拟环境:
    bash
    pyenv shell my-app-env

    这个设置只在当前终端窗口有效。

激活虚拟环境后,你可以像往常一样使用 pip 安装项目依赖:

bash
pip install -r requirements.txt

这些库会安装在当前激活的虚拟环境(my-app-env)中,不会影响其他虚拟环境或全局环境。

退出(deactivate)虚拟环境:

如果你使用了 pyenv shell <env_name> 来临时激活,可以使用 pyenv shell --unset 来取消 shell 级别的设置,Pyenv 会回退到 localglobal 设置。

如果你是通过 pyenv local <env_name> 在目录中激活的,只需要离开该目录即可。Pyenv 会自动切换回适合新目录的版本。

如果你想强制退出当前激活的虚拟环境并使用它所基于的 Python 版本(或再上级的设置),可以使用:

bash
pyenv deactivate

这个命令主要用于从通过传统的 source venv/bin/activate 方式激活的虚拟环境返回,或者当你需要明确取消当前虚拟环境设置时。在使用 pyenv local/shell 管理时,通常不需要手动 deactivate,离开目录或新的 pyenv local/shell 命令会自然切换。

删除虚拟环境:

如果你不再需要某个虚拟环境,可以使用 pyenv uninstall 命令删除它:

bash
pyenv uninstall my-app-env

这个命令会移除 ~/.pyenv/versions/my-app-env 目录及其内容。删除前请确保你已经备份了重要数据(如果虚拟环境中包含了非依赖库的文件)。

其他常用 Pyenv 命令

  • pyenv update:更新 Pyenv 本身
    如果你是通过 Git 克隆安装的 Pyenv,或者使用了 pyenv-update 插件(pyenv-installer 包含),可以使用此命令更新 Pyenv 到最新版本。
    bash
    pyenv update

  • pyenv uninstall <version>:卸载 Python 版本
    如果你不再需要某个 Python 版本,可以使用此命令将其移除。
    bash
    pyenv uninstall 3.9.18

    这个命令会删除 ~/.pyenv/versions/3.9.18 目录。

  • pyenv doctor:检查构建依赖
    如果你安装 Python 时遇到问题,可以使用 pyenv doctor 命令来检查系统是否缺少 Pyenv 构建 Python 所需的关键依赖。此命令需要 pyenv-doctor 插件(pyenv-installer 包含)。
    bash
    pyenv doctor

    它会输出检查结果,告诉你可能缺少哪些库。

故障排除

在使用 Pyenv 过程中,可能会遇到一些问题。以下是一些常见问题及其解决方案:

  1. 安装 Python 失败(缺少构建依赖):
    这是最常见的问题。安装 Pyenv 后,尝试安装 Python 版本时,编译过程可能会中断并报错,提示缺少某个头文件或库。
    解决方案: 仔细阅读错误信息,确定缺少的库或工具的名称。然后根据你的操作系统,使用相应的包管理器(apt, yum, brew)安装这些依赖。回顾本文开头的“构建依赖”部分,确保安装了所有必要的库。安装依赖后,再次运行 pyenv install <version>

  2. python 命令没有指向 Pyenv 管理的版本:
    当你执行 python 命令时,它仍然执行的是系统自带的 Python,而不是 Pyenv 管理的版本。
    解决方案:

    • 检查 Pyenv 的 shell 初始化是否成功。执行 type python,如果输出不是 python is a function 或指向 shims 目录的路径,说明 Pyenv 的 shell 配置没有正确加载。检查 .bashrc, .zshrc 等文件中的 Pyenv 配置行是否正确,并确保你在打开新的终端或手动 source 了配置文件。
    • 确认你已经使用 pyenv global, pyenv local, 或 pyenv shell 命令设置了某个 Pyenv 管理的 Python 版本为当前活动版本。使用 pyenv version 查看当前活动版本及其来源。
    • 执行 pyenv rehash。虽然新版本多数情况下会自动执行,但手动执行一次有时能解决路径问题。
  3. 安装的 Python 版本或虚拟环境在使用 pyenv versions 时不显示:
    解决方案: 执行 pyenv rehash。这会更新 Pyenv 的 shims 目录,确保 Pyenv 能够识别新安装的版本或环境。

  4. pyenv-virtualenv 命令找不到或无法使用:
    解决方案: 确保 pyenv-virtualenv 插件已经正确安装在 $PYENV_ROOT/plugins/pyenv-virtualenv 目录下。如果使用了手动安装方式,确保已经克隆了该仓库。同时,检查你的 shell 配置文件是否包含了 eval "$(pyenv virtualenv-init -)" 并已经重新加载了配置。

  5. 虚拟环境激活后,某些命令(如 activate)仍然找不到:
    解决方案: 当使用 pyenv localpyenv shell 激活由 pyenv-virtualenv 创建的虚拟环境时,你不需要执行传统的 source <env_path>/bin/activate 命令。Pyenv 的 shims 机制会自动将 pythonpip 等命令重定向到虚拟环境中的可执行文件。如果你执行了传统的 activate 脚本,可能会干扰 Pyenv 的 shims 机制,导致意外的行为。依赖 Pyenv 的自动切换即可。

进阶话题(简述)

  • 定制构建: Pyenv 允许你在安装 Python 时传递环境变量来自定义构建过程,例如指定安装路径、启用或禁用某些特性。这通过在 pyenv install 命令前设置环境变量来实现。
  • 离线安装: 如果你需要在没有网络的环境中安装 Python,可以提前下载好 Python 源代码包,放在 Pyenv 的缓存目录 ($PYENV_ROOT/cache) 中,Pyenv 在安装时会优先使用本地缓存。
  • 插件生态: Pyenv 有一个活跃的插件生态,除了 pyenv-virtualenv,还有 pyenv-which-ext (增强 pyenv which 功能), pyenv-update (更新 pyenv 本身) 等。

总结

Pyenv 是一个强大且灵活的 Python 版本管理工具,它通过 shims 机制实现了对多个 Python 解释器的无缝切换,极大地简化了多版本环境下的开发工作。结合 pyenv-virtualenv 插件,Pyenv 与虚拟环境工具完美配合,提供了从解释器版本到第三方库依赖的完整隔离方案。

虽然安装 Pyenv 及其依赖可能需要一些初始投入,并且理解 shims 的工作原理需要一点时间,但一旦掌握,Pyenv 将成为你 Python 开发工具箱中不可或缺的一部分,让你告别版本冲突的烦恼,专注于代码本身。

通过本文的学习,你应该已经能够:
* 理解为什么需要 Pyenv。
* 了解 Pyenv 的安装方法(推荐使用 pyenv-installer)。
* 掌握安装、查看、设置(global, local, shell)Python 版本的基本命令。
* 理解 Pyenv 如何与虚拟环境(特别是 pyenv-virtualenv)配合使用。
* 解决一些常见的安装和使用问题。

现在,就去安装 Pyenv,亲身体验在不同 Python 版本间自由切换的乐趣吧!在你的每一个新项目开始时,养成使用 pyenv local <version> 结合虚拟环境的好习惯,这将为你的开发之路省去无数麻烦。

祝你编程愉快!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部