- 开发工具
- CLI
【免费下载链接】pyenv
Simple Python version management
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
暂时禁用:从 shell 启动配置中移除
pyenv init调用即可。这会从PATH中移除 shims 目录,此后python等命令恢复执行系统 Python。pyenv命令本身仍然可用,但你的 Python 应用不再受版本切换影响。彻底卸载:删除 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:/binPATH中的目录从左到右被搜索,所以列表靠前的目录中的匹配可执行文件优先于靠后的。上例中先搜/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时操作系统会:
- 在
PATH中搜索名为pip的可执行文件; - 在
PATH开头找到名为pip的 pyenv shim; - 运行该 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 版本:
PYENV_VERSION环境变量(若指定)。可用pyenv shell命令在当前 shell 会话中设置;- 当前目录的应用级
.python-version文件(若存在)。可用pyenv local命令修改; - 向上逐级父目录搜索找到的第一个
.python-version文件(直到文件系统根目录); - 全局
$(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 -)"实际做了以下五件事:
- 探测当前 shell:
pyenv init会判断你使用的 shell,因为eval "$(pyenv init -)"的具体输出因 shell 而异。显式指定 shell(如eval "$(pyenv init - bash)")更推荐,能显著减少启动耗时; - 设置 shims 路径:把
$(pyenv root)/shims前置到$PATH,这是 pyenv 透明拦截并重定向python、pip等调用的关键;同时删除PATH上其他位置的$(pyenv root)/shims,从而允许eval "$(pyenv init -)"被多次调用而不产生重复PATH条目; - 安装自动补全:可选但相当有用。加载
<pyenv installation prefix>/completions/pyenv.bash即可启用,同时还有 Zsh、Fish 和 PowerShell 的补全脚本; - 重新生成 shims(rehash):shim 文件需要定期重建,在 init 时执行可确保一切保持最新,也可以随时手动运行
pyenv rehash; - 把
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 的行为:
| name | default | description |
|---|---|---|
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)。
先向
~/.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然后,如果你有
~/.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
若使用 Fish 3.2.0 或更新版本,交互式执行:
set -Ux PYENV_ROOT $HOME/.pyenv test -d $PYENV_ROOT/bin; and fish_add_path $PYENV_ROOT/bin否则执行下面这段:
set -Ux PYENV_ROOT $HOME/.pyenv test -d $PYENV_ROOT/bin; and set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths然后向
~/.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 install | Python-Build 插件 | 下载并源码构建 Python 版本 |
pyenv shell | libexec/pyenv-sh-shell | 设置当前会话的PYENV_VERSION |
pyenv local | libexec/pyenv-local | 读写当前目录.python-version |
pyenv global | libexec/pyenv-global | 读写$(pyenv root)/version |
pyenv rehash | libexec/pyenv-rehash | 重建全部 shims(带锁与去重) |
pyenv exec | libexec/pyenv-exec | 按选中版本调整PATH后执行命令 |
pyenv which | libexec/pyenv-which | 显示 shim 将解析到的真实可执行路径 |
pyenv version-name | libexec/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
相关推荐
Python版本管理器Pyenv安装与使用指南
Python版本管理器Pyenv安装与使用指南 项目介绍 Pyenv 是一个轻量级的Python版本管理工具,遵循UNIX传统的单一目的工具设计理念,它使得在多
开发工具CLIGL3W简明安装与使用指南
GL3W简明安装与使用指南 项目介绍 GL3W 是一个简单但强大的OpenGL核心配置加载器,旨在简化现代OpenGL版本(特别是3.0及以上)在不同平台上的初
Numba CUDA Minor Version Compatibility(MVC)完整指南:原理、安装、启用与源码解析
Numba CUDA Minor Version Compatibility(MVC)完整指南:原理、安装、启用与源码解析 CUDA Minor Version
编译器高性能计算
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考