news 2026/9/30 6:51:50

pyenv 简明指南:Simple Python Version Management 的安装、使用与工作原理全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
pyenv 简明指南:Simple Python Version Management 的安装、使用与工作原理全解析
  • 开发工具
  • CLI

【免费下载链接】pyenv

Simple Python version management

项目地址:https://gitcode.com/GitHub_Trending/py/pyenv
点击查看免费下载

pyenv 是一款遵循 UNIX 单一职责哲学、完全用纯 Shell 脚本实现的 Python 版本管理工具:它允许你在同一台机器上轻松切换多个 Python 版本,支持按用户设置全局版本、按项目设置局部版本,也能通过环境变量临时覆盖版本选择。读完本篇,你将掌握 pyenv 的完整安装流程(Linux/macOS/Windows/WSL)、三大版本切换命令(pyenv shell/pyenv local/pyenv global)、前缀自动解析等进阶用法,并从源码层面理解其 PATH、Shims 与版本选择机制的底层原理。

本文以仓库根目录下的 README.md 为骨架撰写,涉及的实现细节均可在 libexec/ 目录中找到对应源码佐证。


一、pyenv 是什么:能做什么,不做什么

pyenv 的核心定位是一句话:Simple Python version management——简单、不打扰、只做好一件事的 Python 版本管理工具。它源自 rbenv 与 ruby-build 的移植,针对 Python 做了适配改造。

pyenv 能做的事

  • 按用户切换全局 Python 版本(pyenv global);
  • 支持按项目设置 Python 版本(pyenv local,借助.python-version文件);
  • 支持多种 Python 发行版:CPython、PyPy、Stackless Python、Jython 等,可用pyenv install -l查看完整可用版本列表;
  • 允许通过环境变量覆盖 Python 版本(PYENV_VERSION);
  • 同时搜索多个 Python 版本的命令,这在与 tox 配合做跨版本测试时非常有用。

与 pythonbrew、pythonz 相比,pyenv 不做的事

  • 不依赖 Python 自身:pyenv 完全由纯 Shell 脚本写成,不存在"鸡生蛋"的引导(bootstrap)问题;
  • 不需要加载进 Shell:pyenv 通过把 shims 目录加入PATH来工作,而非修改 shell 行为;
  • 不管理 virtualenv:虚拟环境可以由你自行用 virtualenv 创建,或借助 pyenv-virtualenv 插件自动化完成。

实现佐证:仓库根目录的 libexec/pyenv 第一行即#!/usr/bin/env bash,主程序与全部子命令均为 Bash 脚本,没有任何 Python 依赖。


二、安装 pyenv

A. 获取 pyenv

Linux/Unix

如果你装了 Homebrew,也可以直接采用下文 macOS 的 Homebrew 方案。

方式一:自动安装脚本(推荐)

curl -fsSL https://pyenv.run | bash

该脚本来自 pyenv 的姊妹项目 pyenv-installer,会帮你完成克隆、配置环境等一系列初始化动作。

方式二:基础 Git Checkout(适合想 fork 或贡献上游代码的用户)

将 pyenv 克隆到你想安装的位置,推荐$HOME/.pyenv(也可以放别处):

git clone https://github.com/pyenv/pyenv.git ~/.pyenv

可选:编译动态 Bash 扩展以加速 pyenv。编译失败也没关系,pyenv 依然可以正常工作:

cd ~/.pyenv && src/configure && make -C src

实现佐证:仓库中的 src/realpath.c 与 src/Makefile.in 正是这个动态扩展的源码;在 libexec/pyenv 中可以看到,pyenv 启动时会优先尝试enable -f ... realpath加载该原生扩展来加速路径解析,加载失败则回退到纯 Shell 的readlink实现,并(在显式要求原生扩展时)报错退出。

macOS

Linux 的方案同样适用于 macOS,但日常使用更推荐 Homebrew:

brew update brew install pyenv

若想安装(并保持更新到)最新的开发版 head,而不是最新 release:

brew install pyenv --head

装完后继续执行下文"B. 配置 shell 环境"的后续步骤。

可选:消除brew doctor的警告

如果要从源码构建链接 Python 的 Homebrew 配方(如 Tkinter、NumPy),为避免它们意外链接到 pyenv 提供的 Python,可在交互式 shell 配置中加入以下别名:

  • Bash/Zsh:

    alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew'
  • Fish:

    alias brew="env PATH=(string replace (pyenv root)/shims '' \"\$PATH\") brew"
Windows

pyenv 官方不支持 Windows,且在 Windows 原生环境下无法工作,仅在 WSL(适用于 Linux 的 Windows 子系统)中可用。即便如此,WSL 中安装的也是运行在虚拟机里的 Linux 版 Python,而非原生 Windows 版本,无法获得 Windows 特有的功能。

如果你在 Windows 下工作,官方推荐使用 pyenv-win 这个 fork——它才会安装原生 Windows Python 版本。

B. 配置 shell 环境

下面的配置适用于绝大多数用户的常见场景。更详细的选项见后文"Advanced configuration"与"Manual shell setup"。

向当前运行 shell 的启动文件中添加推荐配置,运行<path/to/pyenv> --install即可:

  • 使用安装脚本安装的:

    ~/.pyenv/bin/pyenv init --install
  • 使用 Homebrew 安装的:

    pyenv init --install

注意:对于 Bash,如果BASH_ENV指向.bashrc,应避免走自动--install路径,而是按下文手工 Bash 配置操作,让eval "$(pyenv init - bash)"只出现在登录启动文件中。

C. 重启 shell

让PATH变更生效:

exec "$SHELL"

D. 安装 Python 构建依赖

在安装新 Python 版本之前,务必先安装好 Python 构建依赖(参见 pyenv 官方 wiki 的 "suggested build environment" 页面)。因为绝大多数 pyenv 提供的 Python 版本都是源码发布版,安装时会在本地从源码编译。装好依赖后,就可以开始使用 pyenv 了。

E. 从旧版本升级的注意事项

如果你从 pyenv 2.0.x–2.2.x 升级:

pyenv 2.3.0 起简化了启动逻辑与配置指引,旧的(2.0.0–2.2.5)更复杂的配置方案仍然可用:

  • 定义环境变量PYENV_ROOT指向 pyenv 存储数据的位置,默认为$HOME/.pyenv;如果是 Git checkout 安装,建议设置为你克隆的位置;
  • 如果pyenv可执行文件不在PATH中,请先加入;
  • 运行eval "$(pyenv init -)"把pyenv作为 shell 函数装入当前 shell,启用 shims 与自动补全;
  • 也可以只运行eval "$(pyenv init --path)",仅启用 shims、不做 shell 集成。

三、pyenv 日常使用

安装额外的 Python 版本

使用pyenv install安装新版本,例如安装 Python 3.10.4:

pyenv install 3.10.4

运行pyenv install -l可列出所有可用版本。

关于 Python 发布版的说明:

  • 绝大多数 pyenv 提供的 Python 版本是源码发布版,安装时从源码构建(这也是为什么需要预先安装构建依赖)。你可以通过向 Python 的configure传递选项和编译器标志来自定义构建,详见 Python-Build 的 README 中关于Special environment variables的说明;
  • 安装遇到问题,请参考官方 wiki 的 "Common Build Problems" 页面;
  • 需要代理下载时,设置http_proxy和https_proxy环境变量即可;
  • 若愿意用更长的构建时间换取更快的解释器,参见 Python-Build README 的Building for maximum performance一节。
前缀自动解析到最新版本

除uninstall外,所有 pyenv 子命令都会自动将完整前缀解析为对应版本线的最新版本:pyenv install解析到最新已知版本,其他子命令解析到最新已安装版本。

例如,安装并切换到最新的 3.10 系列版本:

pyenv install 3.10 pyenv global 3.10

可以运行pyenv latest -k <prefix>查看pyenv install会如何解析某个前缀,或pyenv latest <prefix>查看其他子命令的解析结果。

实现佐证:前缀解析逻辑由 libexec/pyenv-latest 实现,并在 libexec/pyenv-version-name 中被调用——当某个版本不存在时,pyenv-version-name会尝试用pyenv-latest -b解析前缀版本号,同时还会去掉显式的python-前缀(如python-3.12归一化为3.12)。

扩展支持(Extended Support)的 Python 版本

对下列 Python 版本,pyenv 会应用用户提供的补丁以支持一些较新的环境。虽然 pyenv 并不主动维护这些补丁,但由于既有版本永不改变,可以认为它们会在后续环境出现不兼容变化之前一直有效:

  • 3.10.x–3.14.x:XCode 27
  • 3.7.8–3.7.15、3.8.4–3.8.12、3.9.0–3.9.7:XCode 13.3
  • 3.5.10、3.6.15:MacOS 11+ 和 XCode 13.3
  • 2.7.18:MacOS 10.15+ 和 Apple Silicon

切换 Python 版本

要选择一个已安装的 Python 作为使用版本,运行以下任一命令:

  • pyenv shell <version>—— 仅对当前 shell 会话生效;
  • pyenv local <version>—— 在当前目录(及其子目录)自动生效;
  • pyenv global <version>—— 对当前用户全局生效。

例如,把上面刚装的 Python 3.10.4 设为全局首选版本:

pyenv global 3.10.4

之后无论何时调用python、pip等命令,运行的都会是 pyenv 提供的 3.10.4 安装中的可执行文件,而不是系统 Python。

使用特殊版本名system可以重置选择,回到系统自带的 Python。

实现佐证:libexec/pyenv-global 会把版本写入$(pyenv root)/version文件(带参数时),无参数时则依次读取version、global、default文件,都没有则回退到system;libexec/pyenv-local 则通过--unset删除.python-version文件、通过写文件来设置局部版本(-f/--force可跳过版本存在性校验)。

同时启用多个版本

可以一次传入多个参数来同时选择多个 Python 版本。例如想同时使用最新的已安装 CPython 3.11 和 3.12:

pyenv global 3.11 3.12

之后每当你运行某个由 Python 安装提供的命令时,这些版本会按指定顺序被搜索。由于 shims 的"透传(fall-through)"行为,system总是会在其后被隐式搜索。

卸载 Python 版本

随着时间推移,$(pyenv root)/versions目录下会积累很多 Python 版本。

移除旧版本用pyenv uninstall <versions>;或者直接rm -rf对应版本的目录,可用pyenv prefix找到某版本的目录,例如pyenv prefix 2.6.8。

注意:插件在卸载时可能执行额外操作,需要你手工补做。例如 Pyenv-Virtualenv 还会移除链接到被卸载版本的所有虚拟环境。

实现佐证:从仓库结构看,版本目录即 pyenv-versions 所列的$(pyenv root)/versions/*目录;libexec/pyenv-prefix 负责输出某个版本对应的安装目录。

其他操作

  • 运行pyenv commands列出所有可用子命令;
  • 对任一子命令加--help查看帮助,或查阅 Commands Reference;
  • 注意:你安装的 pyenv 插件可能自带子命令。

实现佐证:主程序 libexec/pyenv 的分发逻辑是:把第一个参数作为pyenv-<command>查找并执行;找不到时对shell命令提示 "shell integration not enabled",对其他命令提示 "no such command"。这也解释了插件子命令(如plugins/*/bin中的脚本)为何能被自动发现——libexec/pyenv 会把插件 bin 目录与 libexec 目录一并加入PATH。


四、升级与卸载

用 Homebrew 升级

brew upgrade pyenv

想从 release 切换到最新开发 head:

brew uninstall pyenv brew install pyenv --head

之后照常brew upgrade pyenv即可。

用 Installer 或 Git checkout 升级

  • 如果用 pyenv-installer 安装,通常会带有 Pyenv-Update 插件,可一键升级 pyenv 及所有已装插件:

    pyenv update
  • 无论 installer 还是 Git checkout 安装,都可随时用 Git 升级:

    cd $(pyenv root) git pull
  • 想升级到某个特定 release,检出对应 tag:

    cd $(pyenv root) git fetch git tag git checkout v0.1.0

卸载 pyenv

  1. 暂时禁用:从 shell 启动配置中移除pyenv init调用即可。这会从PATH中移除 shims 目录,此后python等命令恢复执行系统 Python。pyenv命令本身仍然可用,但你的 Python 应用不再受版本切换影响。

  2. 彻底卸载:删除 shell 启动配置中所有 pyenv 配置行,然后删除其根目录——这会删除$(pyenv root)/versions/下安装的全部 Python 版本:

    rm -rf $(pyenv root)

    如果通过包管理器安装,最后还要执行包卸载,例如 Homebrew:

    brew uninstall pyenv

五、pyenv 插件机制

pyenv 提供了极其简单的插件扩展方式:创建一个插件目录,并在其特定子路径下放一个 shell 脚本,脚本中的额外逻辑就会在特定时机被运行。

核心理念是:你能放进$PYENV_ROOT/<whatever>的大多数东西,同样可以放进$PYENV_ROOT/plugins/your_plugin_name/<whatever>。

实现佐证:仓库 plugins/ 目录下自带 pyenv-binary、pyenv-link 两个示例插件;libexec/pyenv 启动时会扫描plugins/*/bin加入PATH,并把各插件的etc/pyenv.d、${PYENV_ROOT}/plugins/*/etc/pyenv.d一并纳入PYENV_HOOK_PATH搜索路径。仓库自带的钩子示例包括 pyenv.d/exec/pip-rehash.bash、pyenv.d/install/latest.bash、pyenv.d/rehash/conda.bash 等,展示了钩子的实际放置方式。

插件安装与使用方式,以及常用插件目录,参见官方 wiki 的 Plugins 页面;编写自己的插件,参见 Authoring plugins 页面。


六、工作原理:How It Works

从高层看,pyenv 通过注入PATH的 shim 可执行文件拦截 Python 命令,确定应用指定的 Python 版本,然后把命令转交给正确的 Python 安装执行。

理解 PATH

当运行python或pip时,shell 会按顺序搜索一个目录列表,寻找同名可执行文件。这个列表存放在环境变量PATH中,各目录以冒号分隔:

/usr/local/bin:/usr/bin:/bin

PATH中的目录从左到右被搜索,所以列表靠前的目录中的匹配可执行文件优先于靠后的。上例中先搜/usr/local/bin,再/usr/bin,最后/bin。

理解 Shims

pyenv 通过在PATH最前面插入一个 shims 目录来工作:

$(pyenv root)/shims:/usr/local/bin:/usr/bin:/bin

通过名为rehashing的过程,pyenv 在该目录中为每个已安装版本的所有 Python 命令维护 shim——python、pip等等。

shim 是轻量级可执行文件,仅负责把命令转交给 pyenv。因此装了 pyenv 后,运行pip时操作系统会:

  1. 在PATH中搜索名为pip的可执行文件;
  2. 在PATH开头找到名为pip的 pyenv shim;
  3. 运行该 shim,它把命令转交给 pyenv。

实现佐证:shim 的本质是一段"重新执行自身"的脚本。libexec/pyenv-rehash 中的create_prototype_shim()生成原型 shim 脚本(内容是exec "$(command -v pyenv)" exec "$program" "$@"),随后make_shims $(pyenv-versions --executables)为每个可执行文件复制一份,并借助registered_shims去重、清理过期 shim。pyenv rehash通过.pyenv-shim原型文件实现并发锁与 60 秒超时(PYENV_REHASH_TIMEOUT可调),保证多个 shell 同时 rehash 时的安全。

理解 Python 版本选择

执行 shim 时,pyenv 按以下顺序确定要使用的 Python 版本:

  1. PYENV_VERSION环境变量(若指定)。可用pyenv shell命令在当前 shell 会话中设置;
  2. 当前目录的应用级.python-version文件(若存在)。可用pyenv local命令修改;
  3. 向上逐级父目录搜索找到的第一个.python-version文件(直到文件系统根目录);
  4. 全局$(pyenv root)/version文件。可用pyenv global命令修改。若该文件不存在,pyenv 假定你想用systemPython(见下文)。

关于system版本:特殊版本名system表示使用PATH中 shims 条目之后找到的任意 Python(即"如果 pyenv shims 不在PATH上会运行的那个")。pyenv 将这些安装在它控制之外的 Python 视为一个整体,不加以检查或区分。例如在 macOS 上同时有系统自带 Python 3.8.9 和 Homebrew 装的 3.9.12、3.10.2,对 pyenv 而言仍只是单一的system版本——以你指定名称在PATH上排最前的那个会被执行。

实现佐证:目录逐级搜索逻辑在 libexec/pyenv-version-file 的find_local_version_file()中:从目标目录开始向上逐层检查$root/.python-version,找不到则最终回退输出${PYENV_ROOT}/version。

同时激活多个版本:可以同时激活多个版本,包括多个 Python2 或 Python3 版本,实现 Python2/Python3 并行使用,这也是tox类工具所必需的。例如让 pyenv 优先使用系统 Python 与 Python3(比如 2.7.9 和 3.4.2),同时让 3.3.6、3.2.1、2.5.2 也处于可用状态:先pyenv install缺失的版本,再设置pyenv global system 3.3.6 3.2.1 2.5.2。之后就能用对应的pythonX或pythonX.Y名称调用任意这些版本。

也可以在.python-version文件中手工指定多个版本,每行一个,以#开头的行会被忽略。

实现佐证:多版本选择的核心在 libexec/pyenv-version-name——对PYENV_VERSION按冒号切分,逐版本校验目录是否存在(或通过pyenv-latest解析前缀),最终以冒号连接输出所有生效版本;未安装的版本会报错pyenv: version '...' is not installed (set by ...)并返回非零退出码。

pyenv which <command>用于显示通过 shim 调用<command>时实际会运行哪个真实可执行文件。例如已安装 3.3.6、3.2.1、2.5.2,其中选中了 3.3.6 和 2.5.2,系统 Python 是 3.2.5,那么:

  • pyenv which python2.5应显示$(pyenv root)/versions/2.5.2/bin/python2.5;
  • pyenv which python3显示$(pyenv root)/versions/3.3.6/bin/python3;
  • pyenv which python3.2则因透传行为显示系统 Python 的路径。

实现佐证:libexec/pyenv-which 遍历"选中版本列表 + system",对每个版本检查<prefix>/bin/<command>是否存在(system 则从剔除 shims 后的PATH中command -v查找),命中即输出;全部未命中时给出 "command not found" 与pyenv-whence建议提示,退出码 127。

Shims 的透传(fall-through):如果选中的 Python 安装中都不存在对应可执行文件,shim 会继续透传到PATH上更靠后的位置。这让你可以继续使用系统上其他位置安装的程序,只要它们没有被选中的 Python 安装遮蔽。

定位 pyenv 提供的 Python 安装

一旦 pyenv 确定了应用指定的 Python 版本,它就把命令转交给对应的 Python 安装。

每个 Python 版本被安装到$(pyenv root)/versions下的独立目录中。例如你可能装有:

  • $(pyenv root)/versions/2.7.8/
  • $(pyenv root)/versions/3.4.2/
  • $(pyenv root)/versions/pypy-2.4.0/

就 pyenv 而言,版本名就是$(pyenv root)/versions下的目录名。


七、高级配置(Advanced Configuration)

除非你必须弄清 shell 配置里每一行在做什么,否则可以跳过本节。行为控制环境变量汇总见下文"环境变量"小节。

pyenv init是唯一会把额外命令加载进 shell 的命令。eval "$(pyenv init -)"实际做了以下五件事:

  1. 探测当前 shell:pyenv init会判断你使用的 shell,因为eval "$(pyenv init -)"的具体输出因 shell 而异。显式指定 shell(如eval "$(pyenv init - bash)")更推荐,能显著减少启动耗时;
  2. 设置 shims 路径:把$(pyenv root)/shims前置到$PATH,这是 pyenv 透明拦截并重定向python、pip等调用的关键;同时删除PATH上其他位置的$(pyenv root)/shims,从而允许eval "$(pyenv init -)"被多次调用而不产生重复PATH条目;
  3. 安装自动补全:可选但相当有用。加载<pyenv installation prefix>/completions/pyenv.bash即可启用,同时还有 Zsh、Fish 和 PowerShell 的补全脚本;
  4. 重新生成 shims(rehash):shim 文件需要定期重建,在 init 时执行可确保一切保持最新,也可以随时手动运行pyenv rehash;
  5. 把pyenv作为 shell 函数装入当前 shell:同样可选,但允许 pyenv 及插件改变当前 shell 中的变量——某些命令(如pyenv shell)依赖这一点。sh 分发器不会做覆盖cd、篡改 shell 提示符之类的事;如果出于某种原因需要pyenv是真正的脚本而非 shell 函数,可以安全地跳过这一步。

eval "$(pyenv init --path)"只做第 2、4 项(设置 shims 路径 + rehash)。

想亲眼看看底层发生了什么,运行pyenv init -或pyenv init --path。

  • eval "$(pyenv init -)"应该在任何交互式 shell 启动时运行(包括编辑器派生的嵌套 shell),以获得补全和便捷 shell 函数;
  • eval "$(pyenv init --path)"可以替代前者,仅启用 shims、不做 shell 集成;也可以在其他逻辑向前缀入了可能遮蔽 pyenv shims 的PATH之后,用它把 shims 重新顶到PATH最前。

特别提醒:在 Debian 系发行版中,自带的~/.profile会在 source~/.bashrc之后向前缀入用户级bin目录。由于系统 pip 会把非 root 用户安装的模块可执行文件放进这些用户级bin目录,这类发行版需要同时在~/.profile和~/.bashrc中追加pyenv init调用。

实现佐证:仓库 completions/ 目录下提供 pyenv.bash、pyenv.zsh、pyenv.fish、pyenv.pwsh 四套补全脚本;pyenv init对应实现见 libexec/pyenv-init。

不使用 shims 使用 pyenv

如果不想用pyenv init和 shims,你仍然可以享受 pyenv 安装 Python 版本的能力:运行pyenv install,版本会出现在$(pyenv root)/versions下,你可以手动执行或符号链接它们;或者在你希望命令受当前版本选择影响时,使用pyenv exec <command>。

pyenv exec通过在<command>的环境中把$(pyenv root)/versions/<selected version>/bin前置到PATH来工作——这与 RVM 的做法一致。

实现佐证:libexec/pyenv-exec 先调用pyenv-version-name -f解析当前版本,再用pyenv-which定位真实可执行文件,仅当目标在$(pyenv root)之下(非 system 版本)时把<bin>目录加入PATH,最后exec该命令。

从基于 Python 的程序运行嵌套 shell

除了修改PATH,pyenv exec还会在被执行程序的环境中设置PYENV_VERSION,以确保它不会自发切换到其他 Python 版本。

某些基于 Python 的程序(如 Jupyter)会派生出嵌套 shell 会话。此类 shell 中的pyenv version会如实报告当前版本是由环境变量设置的。

视使用场景不同,这种"版本锁定"可能并不理想。此时需要直接修改或取消该环境变量(或用pyenv shell)。可以在 shell 的交互式启动文件中自动化这一过程——通过派生程序设置的某个特征环境变量来检测嵌套 shell 会话。例如 Jupyter 的场景(截至本文写作时)特征变量是JUPYTER_SERVER_ROOT,对应的~/.bashrc行可能长这样:

[[ -n $JUPYTER_SERVER_ROOT ]] && unset PYENV_VERSION

环境变量

以下环境变量可以影响 pyenv 的行为:

namedefaultdescription
PYENV_VERSION指定要使用的 Python 版本。
另见pyenv shell
PYENV_ROOT~/.pyenv定义 Python 版本与 shims 所在的根目录。
另见pyenv root
PYENV_DEBUG输出调试信息。
等价写法:pyenv --debug <subcommand>
PYENV_HOOK_PATH见 wiki冒号分隔的、用于搜索 pyenv hooks 的路径列表
PYENV_DIR$PWD开始搜索.python-version文件的目录

实现佐证:libexec/pyenv 中--debug会导出PYENV_DEBUG=1并开启set -x追踪;libexec/pyenv 中PYENV_ROOT默认为${HOME}/.pyenv、PYENV_DIR默认为$PWD,并会把两者导出;PYENV_HOOK_PATH则在启动时由 pyenv 自身目录、插件etc/pyenv.d及各系统路径共同拼装而成(libexec/pyenv)。

另参见 Python-Build README 中Special environment variables一节,那里列出了可自定义构建过程的环境变量。

手动 shell 配置

以下是pyenv init --install会写入 shell 启动文件的推荐配置。

要为不同于当前运行 shell 的其他 shell自动安装 pyenv,运行:

path/to/pyenv --install <shell executable name>

例如~/.pyenv --install bash。

Bash

各发行版的 Bash 启动文件差异很大(谁 source 谁、什么条件下、什么顺序、附带什么额外配置各不相同),因此最可靠的做法是:同时把 pyenv 配置追加到.bashrc(用于交互式 shell)和 Bash 会使用的 profile 文件(用于登录 shell)。

  1. 先向~/.bashrc追加:

    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc echo 'eval "$(pyenv init - bash)"' >> ~/.bashrc
  2. 然后,如果你有~/.profile、~/.bash_profile或~/.bash_login,也把命令加进去;若都没有,创建~/.profile并加入:

    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile echo 'eval "$(pyenv init - bash)"' >> ~/.profile

    或加进~/.bash_profile:

    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile echo 'eval "$(pyenv init - bash)"' >> ~/.bash_profile

Bash 警告:某些系统把BASH_ENV配置为指向.bashrc。这类系统上,几乎肯定应该把eval "$(pyenv init - bash)"放进.bash_profile而不是.bashrc,否则可能出现奇怪行为,比如pyenv陷入无限循环(参见上游 issue #264)。

Zsh

向~/.zshrc追加:

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc echo 'eval "$(pyenv init - zsh)"' >> ~/.zshrc

若还想在非交互式登录 shell 中使用 pyenv,同时把命令加到~/.zprofile或~/.zlogin。

Fish
  1. 若使用 Fish 3.2.0 或更新版本,交互式执行:

    set -Ux PYENV_ROOT $HOME/.pyenv test -d $PYENV_ROOT/bin; and fish_add_path $PYENV_ROOT/bin
  2. 否则执行下面这段:

    set -Ux PYENV_ROOT $HOME/.pyenv test -d $PYENV_ROOT/bin; and set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths
  3. 然后向~/.config/fish/config.fish追加:

    pyenv init - fish | source
Nushell

向config.nu追加以下内容,把 pyenv 及其 shims 加入PATH。目前不支持shell 集成(补全与改变 shell 状态的子命令):

$env.PYENV_ROOT = "~/.pyenv" | path expand if (( $"($env.PYENV_ROOT)/bin" | path type ) == "dir") { $env.PATH = $env.PATH | prepend $"($env.PYENV_ROOT)/bin" } $env.PATH = $env.PATH | prepend $"(pyenv root)/shims"
Microsoft PowerShell

向$profile.CurrentUserAllHosts追加:

echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"' >> $profile.CurrentUserAllHosts echo 'if (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) { $Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }' >> $profile.CurrentUserAllHosts echo 'iex ((pyenv init -) -join "`n")' >> $profile.CurrentUserAllHosts

八、深入源码:命令参考与测试

命令参考

所有子命令的完整参考见 COMMANDS.md,涵盖pyenv install、pyenv shell、pyenv local、pyenv global、pyenv exec、pyenv which、pyenv latest、pyenv prefix、pyenv uninstall、pyenv rehash等的完整用法。本文涉及的核心命令均由 libexec/ 目录下的同名脚本实现,读者可直接阅读源码印证行为:

命令实现文件核心职责
pyenv(主分发器)libexec/pyenv解析--debug,设置PYENV_ROOT/PYENV_DIR/PYENV_HOOK_PATH,按pyenv-<cmd>分发
pyenv installPython-Build 插件下载并源码构建 Python 版本
pyenv shelllibexec/pyenv-sh-shell设置当前会话的PYENV_VERSION
pyenv locallibexec/pyenv-local读写当前目录.python-version
pyenv globallibexec/pyenv-global读写$(pyenv root)/version
pyenv rehashlibexec/pyenv-rehash重建全部 shims(带锁与去重)
pyenv execlibexec/pyenv-exec按选中版本调整PATH后执行命令
pyenv whichlibexec/pyenv-which显示 shim 将解析到的真实可执行路径
pyenv version-namelibexec/pyenv-version-name解析当前生效的版本列表

测试与开发

pyenv 的源码托管在 GitHub;测试使用 Bats。仓库 test/ 目录下提供了与本文内容一一对应的测试用例,例如:

  • local.bats 验证pyenv local的读写与--unset;
  • global.bats 验证pyenv global的多版本与回退逻辑;
  • shims.bats 验证 shim 列表与 rehash;
  • which.bats 验证pyenv which的解析与 system 透传;
  • version-name.bats 验证版本选择的优先级与错误提示;
  • version-file.bats 验证.python-version的逐级目录搜索;
  • pip-rehash.bats 验证 pip 安装后自动 rehash 的钩子行为。

欢迎通过 issue tracker 提交 bug 与 pull request,贡献指南见 CONTRIBUTING.md。版本历史见 CHANGELOG.md,许可协议为 MIT License。


结语

从安装到日常使用,再到 shim 与版本选择的底层机制,pyenv 始终贯彻着"简单、单一职责"的设计哲学:纯 Shell 实现、无 Python 引导依赖、通过PATH前置 shims 实现透明拦截。配合pyenv shell/local/global三级版本作用域、前缀自动解析、多版本并行选择与透传机制,你可以在同一环境里从容应对跨项目、跨版本的 Python 开发与测试需求。

  • 开发工具
  • CLI

【免费下载链接】pyenv

Simple Python version management

项目地址:https://gitcode.com/GitHub_Trending/py/pyenv
点击查看免费下载
上一篇:Teable:企业级无代码PostgreSQL平台的技术架构与私有化部署实践
下一篇:SumatraPDF 中的 SyncTeX 解析器:TeX 源文件与 PDF 双向同步技术全解

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 6:50:28

25.STM32H743 FDCAN

FDCAN&#xff08;Flexible Data-Rate CAN&#xff09;是CAN总线的升级版本&#xff0c;兼容传统CAN 2.0&#xff0c;同时支持更高的传输速率&#xff08;数据段最高8Mbps&#xff09;和更大的单帧数据量&#xff08;64字节&#xff0c;传统CAN仅8字节&#xff09;。STM32H743内…

作者头像 李华
网站建设 2026/9/30 6:50:11

Cog CLI 完整实操指南:5 分钟把机器学习模型容器化部署上线

Cog CLI 完整实操指南&#xff1a;5 分钟把机器学习模型容器化部署上线 【免费下载链接】cog Containers for machine learning 项目地址: https://gitcode.com/GitHub_Trending/co/cog Cog CLI 是容器化机器学习模型部署的命令行工具&#xff1a;你只需用 Python 写模型…

作者头像 李华
网站建设 2026/9/30 6:49:35

少儿编程教学实录:用Python 写一个猜数字游戏,讲透输入校验与循环

在青少年编程课上&#xff0c;「猜数字」是我最常用的第一个综合练习。它足够小&#xff0c;一次课就能写完&#xff1b;又足够完整&#xff0c;把输入、类型转换、循环、条件判断、随机数这几件事都串起来了。下面把这节课的完整教学思路整理出来。 一、为什么选这个案例 结果…

作者头像 李华