ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

JupyterLab与conda虚拟环境:手把手教你注册kernel并切换环境

2026/9/30 18:51:15 拓冰建站 浏览量
JupyterLab与conda虚拟环境:手把手教你注册kernel并切换环境 写这篇东西的起因是我在社群里又双叒叕看到有人在问“为什么我 conda activate 切到了某个虚拟环境JupyterLab 里 import 的还是 base 环境的包”或者是“JupyterLab 里怎么才能看到我新创建的那个 conda 环境”说实话这个问题几乎每隔几天就会出现一次而且每次版本更新、每次有人换了新电脑它就会重新冒出来。今天干脆把它彻底讲透把 JupyterLab 和 Anaconda 虚拟环境之间的那层“窗户纸”捅破顺便把我这几年实际踩过的坑和总结出来的经验一起放进来了。先说明白一个最关键的前提JupyterLab 里你是看不到“conda 环境”这个概念的。你只能看到kernel。我们做的一切操作本质上是把 conda 环境“包装”成一个 Jupyter 能识别的 kernel然后在 JupyterLab 的界面里去切换这些 kernel从而间接实现“切换 Python 虚拟环境”的效果。搞不懂这一点后面所有操作都会觉得莫名其妙。先说说文章适合谁刚装了 Anaconda、正在被环境问题折磨的 Python 新手以及用 JupyterLab 做数据分析、机器学习发现环境切换总是不对劲的老手。这篇不是速查清单我会把原理和命令一起讲看完你不仅能照着做还能明白“为什么要这么做”。1. 先理解为什么 JupyterLab 看不到你的 conda 环境1.1 核心概念JupyterLab 只认 kernel不认 conda很多人第一次接触 Anaconda 时心里会建立一个隐含的模型conda 可以创建多个虚拟环境每个环境里有一套独立的 Python 解释器和第三方库那我只要在终端里conda activate 某个环境整个系统——包括 JupyterLab——就应该跟着走。这个模型在命令行场景下基本成立但在 JupyterLab 这个场景下它完全是错的。原因在于 JupyterLab 的架构设计。JupyterLab 本身只是一个 Web 前端负责渲染 Notebook 界面、管理文件、展示输出。真正执行 Python 代码的是一个独立的kernel 进程。你每打开一个 NotebookJupyterLab 就会根据这个 Notebook 关联的 kernel 规范kernel spec去启动一个 Python 解释器进程这个进程才是真正跑代码的“工人”。问题来了kernel 不是凭空出现的它必须提前被“注册”到 JupyterLab 能发现的位置。JupyterLab 启动时会去系统几个固定的目录里寻找所有可用的 kernel 规范包括用户目录下的~/Library/Jupyter/kernelsmacOS、%APPDATA%\jupyter\kernelsWindows、~/.local/share/jupyter/kernelsLinux还有 Anaconda 安装目录下的share/jupyter/kernels等。它只会列出这些目录里注册过的 kernel至于你有多少个 conda 环境、conda 环境叫什么名字JupyterLab 根本“不知道”。用一个生活化的比方conda 环境是一群住在不同小区的“工人”JupyterLab 是一个“招工平台”。平台不会自动知道每个小区里有哪些工人只有工人们到平台登记过注册 kernel平台才能在页面上显示出来供你选择。我们后面要做的就是帮各个 conda 环境里的 Python 解释器进行“登记”。1.2 为什么 conda activate 切换不了 JupyterLab 的 Python 版本这就解释了另一个常见误区很多人以为在终端里conda activate 环境A然后再启动jupyter labJupyterLab 里就跑的是环境A 的 Python。这个认知有一半是对的但很容易踩坑。如果你是在 Anaconda 的基础环境base里执行conda activate 环境A然后继续在这个终端窗口里输入jupyter lab那么启动 JupyterLab 的这个 Python 进程确实是环境A 的 python但 JupyterLab 页面里新建的 Notebook默认用的 kernel 仍然是 JupyterLab 自己找到的第一个可用 kernel——绝大多数情况下是 base 环境注册的那个python3kernel。页面里代码用的解释器和启动 JupyterLab 的进程用的解释器是两码事。这就像你开了一家餐馆启动 JupyterLab餐馆装修时用的工人是环境A 的人启动进程但后厨真正炒菜的厨师kernel你根本没换还是原来那批base 的 kernel。所以很多同学切了半天环境发现 Package 版本怎么都变不了就是这个原因。正确的心智模型是一个 conda 环境要想在 JupyterLab 里被使用必须事先把它注册为一个 kernel。注册之后你可以在 JupyterLab 的 Launcher 界面的 Notebook 列表里看到它的名字或者在已有 Notebook 的 Kernel 菜单里随时切换。切过去之后代码由该环境的 Python 解释器执行包列表自然也就是那个环境里的包。1.3 所有方案的底层逻辑既然搞清楚了原理我们就可以把目标拆成两件事第一让目标 conda 环境具备成为一个 Jupyter kernel 的能力第二让 JupyterLab 能在启动时发现这个 kernel。只要这两个目标达成JupyterLab 里切换环境就是一个下拉菜单的事。实现的路径不止一条手动在每个目标环境里安装ipykernel然后用python -m ipykernel install的方式注册 kernel。这是最经典、最可控、也最适合理解原理的方法我强烈建议新手至少亲手做一遍。在 base 环境里安装nb_conda_kernels插件让它自动扫描并暴露所有 conda 环境。这种方式一劳永逸不用每个环境都手动注册适合环境很多的场景。不注册 kernel直接在激活某个环境后用该环境里的 Python 启动一个全新的 JupyterLab 服务。这个方式简单直接但和“在一个 JupyterLab 里切换环境”是完全不同的体验。下面我依次展开你根据自己情况选方案。我个人建议先把方案一亲手跑通理解之后再上方案二。2. 动手前的环境确认2.1 确认 Anaconda 版本与 JupyterLab 是否已安装在开始注册 kernel 之前先把底子摸清。打开终端Windows 下建议用 Anaconda PromptmacOS/Linux 用普通终端即可分别跑一下下面几条命令conda --version conda env list jupyter lab --version第一条命令确认 conda 本身是可用的第二条命令列出你当前机器上所有的 conda 环境后面注册 kernel 时要用到环境名第三条命令确认 JupyterLab 已安装且版本正常。如果你还没装 JupyterLab在 base 环境里执行conda install -n base jupyterlab -c conda-forge这里我习惯把 JupyterLab 装在 base 环境而不是每一个环境里都装一份。因为 JupyterLab 是前端工具它只需要一份就够了前端要连接的 kernel也就是各种 Python 环境才是真正需要分散部署的“后厨人员”。这个策略能省不少磁盘空间也避免了版本混乱。另外提醒一点新版 Anaconda 默认自带的可能是 Jupyter Notebook 而不是 JupyterLab但现在 JupyterLab 才是主流如果发现jupyter lab命令不存在直接用上面那条命令补上即可。JupyterLab 3.x 和 4.x 的操作差别不大本文命令在这两个大版本下都可用。2.2 列出环境并确定目标环境名确认完成后看conda env list的输出格式大概是这样的# conda environments: # base * /opt/anaconda3 data_analysis /opt/anaconda3/envs/data_analysis deeplearning /opt/anaconda3/envs/deeplearning第一列是环境名称第二列是该环境 Python 解释器所在的绝对路径。带星号*的是当前终端里激活的环境。这里我要强调一个很有用的认知环境名本质上只是 conda 给某个目录起的别名真正决定“这是哪个环境”的是它后面那串路径。后面你如果手工改 kernel.json理解了路径就理解了所有问题。下一步明确你希望 JupyterLab 里出现哪些环境。比如我有data_analysis和deeplearning两个环境分别是数据分析场景和深度学习场景那我的目标就是让这两个名字出现在 JupyterLab 的 kernel 列表里。2.3 理解 ipykernel 的角色在正式操作前还有最后一个概念需要讲清楚ipykernel是什么为什么它必不可少。ipykernel是 Jupyter 生态里负责“翻译”的组件。JupyterLab 前端通过 HTTP/WebSocket 和 kernel 进程通信向前端发送的是 JSON 格式的交互协议消息Python 解释器本身不会说这种“语言”而ipykernel就是在 Python 解释器里装的一个“翻译官”它把 Jupyter 协议消息翻译成 Python 代码执行的指令再把执行结果翻译回 JSON 消息发给前端。打个比方前端是中国的老板Python 解释器是只会说 Python 的外籍厨师ipykernel就是那个双方都听得懂的翻译员。没请翻译老板JupyterLab就算看到了厨师conda 环境也没法让他干活。所以每一个你想在 JupyterLab 里使用的 conda 环境都必须装上ipykernel。这一步不能省也不是良性可选项。3. 最常用的方案给每个环境手动注册 kernel3.1 激活目标 conda 环境现在开始正式操作。打开终端激活你想要注册的那个 conda 环境conda activate data_analysis激活完成后命令行提示符前面会出现(data_analysis)字样。这一步的意义是让后续所有操作都在该环境的上下文里执行。这里有一个 Windows 用户特别容易踩的坑如果你在 cmd 或 PowerShell 里执行conda activate报错说这个命令不存在那是因为你还没执行过conda init。解决办法是在 Anaconda Prompt 里先跑一次conda init然后重新打开一个终端窗口即可。这是 Anaconda 安装后最常见的初始化问题没有之一。3.2 在环境内安装 ipykernel激活环境后安装ipykernel。我强烈推荐用 conda 安装而不是 pip尤其是在 Windows 上conda install ipykernel如果网络不太好可以先给 conda 配置国内镜像源再装比如清华源或中科大源。用 conda 而不是 pip 的理由有两个第一conda 会一并解决ipykernel依赖的底层库比如pyzmq这类编译型 Python 包的二进制文件问题避免 pip 在某些系统上还要现场编译导致报错第二conda 安装会把包完整放进当前环境指定的site-packages里不会出现 pip 把包装错位置的诡异情况。你可能会问“那我之前没在这个环境里装过 Jupyter 生态的任何东西直接装 ipykernel 行不行”答案是完全可以。ipykernel不自带前端界面它只提供 kernel 能力。你不需要在每个环境里重复安装 JupyterLab这也再次印证了前面说的“前端只留一份”策略。3.3 执行 kernel 注册命令装好ipykernel之后在这个已激活的环境里执行注册命令python -m ipykernel install --user --name data_analysis --display-name Python (data_analysis)我来逐个拆解这几个参数搞清楚它们你以后就不会对这条命令感到陌生了python -m ipykernel表示调用当前环境下 Python 解释器中的ipykernel模块。注意这里一定是在激活目标环境后执行确保用的是目标环境里的python解释器。install安装一个 kernel 规范到本机。--user将 kernel 规范安装到当前用户的 Jupyter 配置目录而不是系统级目录。加了--user不需要管理员/root 权限而且只对当前用户生效最安全。如果省略在 Anaconda 安装目录具备系统写权限时也可能写到Anaconda/share/jupyter/kernels下但这可能污染全局配置一般不推荐。--name这是 kernel 的内部标识名Jupyter 会用它作为目录名存放 kernel 配置。name 建议全小写、用下划线或连字符连接不要含空格和中文因为它在底层就是文件夹名。最方便的做法是直接等于 conda 环境名见名知意。--display-name这是 JupyterLab 界面上显示出来的名字你可以随便起中文也支持。写成Python (data_analysis)这种格式新打开 Launcher 页面时你就会在 Notebook 的图标下看到这个名字一目了然。执行完毕终端会提示Installed kernel spec data_analysis in ...这样一行路径信息。按同样的流程把你想用的其他环境也依次注册一遍。3.4 在 JupyterLab 里验证效果注册完成后回到 JupyterLab 页面。这里有个细节要特别注意如果你在注册 kernel 之前就已经打开着 JupyterLab页面通常不会自动刷新出新的 kernel因为 JupyterLab 在启动时会建立一次 kernel 列表的缓存。所以此时你需要刷新浏览器页面建议CtrlShiftR强制刷新或者干脆重启 JupyterLab 服务进程。刷新之后你会在两个地方看到效果。第一个地方是 Launcher 页面点击左上角打开新的 Launcher在 Notebook 区域会出现一个Python (data_analysis)的图标点击它新建的 Notebook 就运行在data_analysis环境的 Python 解释器上。第二个地方是已有 Notebook 的右上角或菜单栏你可以在已打开的 Notebook 里通过Kernel菜单 →Change Kernel…在弹窗里把当前 Notebook 切换到你刚刚注册的Python (data_analysis)。切换后如果代码里之前有过执行结果最好重启一下内核Kernel→Restart Kernel and Run All Cells让所有变量重新加载否则会出现变量是上一套环境产生的、代码却在新环境下执行这种别扭状态。验证做得对吗在 Notebook 的第一格输入以下代码运行一下import sys print(sys.executable)如果输出的路径指向/opt/anaconda3/envs/data_analysis/bin/pythonWindows 下是...\envs\data_analysis\python.exe那说明你已经成功把该环境接到了 JupyterLab 上恭喜最核心的问题已经解决了。4. 一劳永逸的方案用 nb_conda_kernels 自动注册所有环境4.1 nb_conda_kernels 是怎么帮你干活的手动注册的方式直观但有个现实问题如果你有七八个环境每个环境都要激活、装 ipykernel、执行注册命令重复劳动不说后面新建环境还得记得再来一遍。有没有办法让 JupyterLab 自动识别所有 conda 环境答案是有的那就是nb_conda_kernels插件。这个插件的使用方式非常反直觉但也非常优雅你只需要在 base 环境里安装它然后它会去扫描器上所有 conda 环境自动为那些“能作为 kernel 运行的环境”生成内核入口。换句话说它干了你本来要手动重复 N 遍的活儿。安装命令conda install -n base nb_conda_kernels -c conda-forge安装完成后重启 JupyterLab。你再打开 Launcher 或者切换 kernel 时会发现列表里自动多出了所有 conda 环境的名字。这里要讲一下它的“识别”机制不然你会困惑为什么有些环境出现、有些环境不出现。nb_conda_kernels并不是无脑列出所有环境它会检查每个环境里是否安装了ipykernel。如果一个环境连ipykernel都没有它无法把该环境当作一个可用的 Python kernel 来注册这种情况下你就会发现列表里缺了某个环境。所以完整的流程是先在 base 里装好插件然后对你需要的每个 conda 环境都要激活并执行conda install ipykernel。注意装了插件之后这一步依然不能省“是否具备 ipykernel”是插件识别环境的开关。但好处是你不用再手动执行python -m ipykernel install注册命令了插件会替你批量处理。4.2 nb_conda_kernels 的最佳实践与注意点这种方案适合什么样的场景我认为最适合那些环境较多、且经常增删环境的重度用户。比如我同时维护数据清洗、机器学习、深度学习、爬虫四个环境用这个插件我只需要管好每个环境里有没有 ipykernel新增环境时也只需装个 ipykernel 就完了JupyterLab 重新刷新一下新环境自动出来。用这个方案有几点教训是很多教程不会提的第一插件装好后建议把 JupyterLab 的服务进程彻底停掉再重启而不是只刷新浏览器。有些版本里kernel 列表的刷新依赖服务端重新扫描光在浏览器里强制刷新不够。第二环境命名为英文小写字母加下划线别用中文。虽然 nb_conda_kernels 能识别但中文环境名在某些情况下会在内部路径处理上出现编码问题尽管现在新版好很多但何必给自己添麻烦。第三如果你后来删除了某个 conda 环境JupyterLab 里的对应 kernel 条目应该也会随着扫描消失。万一没消失重启一次 JupyterLab 服务进程就干净了。第四用 nb_conda_kernels 之后kernel 的显示名称一般是Python [conda env:环境名]这种格式。习惯了就很好认但我个人觉得不如手动注册时设置的Python (data_analysis)看起来干净。当然这只是审美问题不影响功能。5. 另外两种应急情况的操作思路5.1 直接在激活环境中启动独立的 JupyterLab 服务有一种常见需求是你不想轻易改动太多环境、只是想临时在这个环境里跑一下代码并看看效果。这时最简单粗暴的方法是激活该环境然后在该环境中直接启动 JupyterLabconda activate deeplearning pip install jupyterlab ipykernel jupyter lab这样启动的 JupyterLab 服务完全运行在deeplearning环境里默认的新建 Notebook 也会使用该环境的 Python。页面里依然只有一个python3kernel但这个python3指向的就是当前环境的解释器。这个方式的限制很明显第一每次要切环境都得重启 JupyterLab 服务无法在同一个页面上切换第二该环境里必须安装了 JupyterLab 本体这和我们“前端只保留一份”的策略相悖多装一份就多占一份空间、多一份版本同步负担。所以我一般只在排查问题比如怀疑是 JupyterLab 前端版本导致的问题时才用这个方式日常使用不推荐。5.2 手动改 kernel.json 指向任意 Python 解释器还有一种场景是某个 conda 环境因为各种原因你已经没法在里面成功安装 ipykernel 了但你就是想用它的解释器。这时候可以手工创建一个 kernel 规范直接指定解释器路径。先看看当前已有的 kernel 规范和它们的目录位置jupyter kernelspec list输出类似Available kernels: python3 /opt/anaconda3/share/jupyter/kernels/python3 data_analysis /Users/yourname/Library/Jupyter/kernels/data_analysis每个 kernel 对应的目录里有一个kernel.json文件它定义了启动 kernel 时执行的命令。你可以自己新建一个目录并手动写一个kernel.json内容模板如下{ argv: [ /opt/anaconda3/envs/deeplearning/bin/python, -m, ipykernel_launcher, -f, {connection_file} ], display_name: Python (deeplearning_manual), language: python, metadata: { debugger: true } }其中argv第一项改成目标环境里 Python 解释器的绝对路径。macOS/Linux 路径一般在envs/环境名/bin/pythonWindows 在envs\环境名\python.exe。保存后重启 JupyterLab就能看到你手工定义的那个 kernel 了。但请注意即使手工指定了解释器路径Jupyter 在启动 kernel 时仍会尝试通过ipykernel_launcher这个入口拉起内核。也就是说这个环境里必须在 site-packages 中存在完整的ipykernel包否则依然会启动失败。手工改 json 解决不了“环境里没有 ipykernel”这个根本问题它更适合的是那些 ipykernel 存在但 kernel 注册信息损坏的场景比如说你把环境目录搬迁过、原 kernel 路径失效了。所以这个方案我给它的定位是“修复手段”而不是“常规通道”。6. 高频问题排查与避坑记录6.1 常见问题速查表把这几年来看到的高频问题整理成一张表按“先看现象、再查原因、最后解决”的顺序来组织现象可能原因解决办法注册完 kernel 后 JupyterLab 里看不到JupyterLab 服务端缓存了旧的 kernel 列表强制刷新浏览器若无效彻底重启 jupyter lab 进程kernel 列表有名字但点开一直显示启动失败该环境的 ipykernel 版本不兼容或缺失激活该环境后conda install --force-reinstall ipykernel重启 JupyterLab选了环境名但 import 的包还是 base 环境的注册时没有在目标环境里执行命令或环境名标识错误用sys.executable打印解释器路径检查确认注册命令是在激活环境后执行在 Windows 上 conda activate 报错conda 尚未初始化 shell在 Anaconda Prompt 里执行conda init后重新打开终端删除 conda 环境后 JupyterLab 还残留条目kernel 规范文件仍然留在 kernels 目录执行jupyter kernelspec remove 环境名nb_conda_kernels 装好但某些环境不出现目标环境里没有安装 ipykernel逐个环境激活后安装 ipykernelpip 包装了但 notebook 里 import 提示不存在notebook 当前选中的 kernel 不是该 pip 包所在的环境检查 kernel 选择确认 pip 是在正确环境里执行环境解释器路径变更导致 kernel 启动失败比如 Anaconda 目录被移动过kernel.json 里还是旧路径用jupyter kernelspec list找到 kernel 目录更新kernel.json中的路径写清楚之后我再补充几个排查逻辑上的建议。遇到 kernel 相关的问题不要急着搜报错第一步永远是确认“当前 notebook 到底用的哪个解释器”。直接在 notebook 里运行import sys print(sys.executable)这一步能定位一半以上的问题。如果打印出来的路径不是目标环境的 python那环境切换就是失败的后面所有包的行为都会对不上这时候再回头看是不是注册、激活、选择这哪步出了问题。6.2 几条实实在在的实操心得最后分享几条比较个人的经验都是踩过坑换来的。第一环境名和 kernel 名尽量统一。我有一个习惯新创建一个 conda 环境时环境名就叫data_analysis注册 kernel 时--name data_analysis这样我在终端和 JupyterLab 两边的认知是一致的。JupyterLab 界面里display-name可以写得冗余一点、友好一点那是给别人看的name和路径是给机器看的一定要简洁规范。第二Windows 用户特别注意别在 PowerShell 的默认蓝色窗口里执行conda install ipykernel之后又跑到普通 cmd 里去启动 JupyterLab。不同的 shell 环境变量加载方式不同容易造成“明明装了为什么找不到”的假象。统一用 Anaconda Prompt或者把一个 shell 用到底别来回切换。第三如果你使用 VS Code 里的 Jupyter 插件那它的 kernel 管理逻辑和 JupyterLab 是共享同一套 kernel 注册机制的。你在命令行里注册好的 kernelVS Code 里通常也能直接选到不用重复操作。第四关于包的安装策略。我强烈建议数据分析、机器学习类的包尽量用 conda 安装而不是 pip因为 conda 能自动处理非 Python 的二进制依赖比如 CUDA 相关的库、MKL、OpenBLAS。有时候你在 JupyterLab 里选了正确的环境却还是会遇到import numpy报错缺少某些底层库十有八九是当初用 pip 硬装的包没带上系统级依赖。这是 conda 环境管理里数一数二的大坑。第五jupyter kernelspec list和jupyter kernelspec remove是排查时最好用的两个命令。前者查看当前注册了哪些 kernel 以及路径后者可以把注册坏掉的 kernel 规范清理掉。操作不可逆所以用remove的时候要确认你删的就是那个要废弃的 kernel。我在实际使用中的习惯是所有环境统一在初始创建时就装好 ipykernel再在 base 里装一个 nb_conda_kernels 作为兜底双保险。手动注册那套方法我虽然讲得很细但现在主要用来做排查和应急日常靠插件自动扫描更省心。如果你刚上手我建议先把第三节的手动方案完整跑通一次再做第四节的一劳永逸方案因为原理清楚之后效率工具才不容易变成黑盒子。你被 JupyterLab 环境切换折磨过吗按上面的步骤试完大概率能干干净净地把环境给你理顺了。