☰
Ubuntu 22.04 安装 Anaconda 与 Jupyter 配置指南
2026/10/1 5:03:16 网站建设 项目流程

1. Ubuntu 22.04 上到底是装 Anaconda 还是自己折腾 Python

Ubuntu 22.04 LTS 自带的是 Python 3.10,/usr/bin/python3这个解释器被系统里一堆组件牵着用——apt的部分子模块、GNOME 的一些脚本、ubuntu-advantage-tools都依赖它。我见过最惨的一次是有人图省事,把系统 Python 的软链接指到了自己编译的 3.12 上,结果第二天Software Updater打不开,终端里apt各种报ModuleNotFoundError,最后只能重装。这是我把数据科学环境彻底和系统解释器隔离的起点,也是这篇内容要讲的核心:在 Ubuntu 22.04 上搭一套 Anaconda 环境,再在里面装 Jupyter Notebook,全程不动系统 Python 一根汗毛。

Anaconda 本质上是一个"自带 Python 的发行版 + 包管理器 + 环境管理器"。它带来的东西有三样是我离不开的:

  • 一个受控的解释器:~/anaconda3/bin/python和系统的/usr/bin/python3完全独立,升级、降级互不影响。
  • conda 的二进制依赖求解:像numpy、scipy、pytorch这类带编译扩展、依赖 BLAS/LAPACK 的包,conda 会把预编译好的二进制和它的运行库一起装上,不需要本机有编译工具链。这一点在服务器上(尤其是没装build-essential的新机器)非常关键。
  • 环境隔离:一个项目一个环境,A 项目要numpy 1.x,B 项目要numpy 2.x,互不打架。

当然它也不是没有代价。Anaconda 装完大概占 5 GB 上下,base环境里塞了一千多个包,很多人根本用不到。更现实的问题是 Anaconda 官方仓库的商业使用条款这几年收紧了,不少公司在合规上会要求员工改用 conda-forge 生态(Miniforge / Miniconda 就是这个路子)。所以我的建议是这样分的:

方案体积适合谁主要代价
Anaconda 发行版约 5 GB,1500+ 包开箱可用教学、个人学习、懒得挑包的人占空间、base 容易越用越脏
Miniconda约 600 MB,只有 conda + python服务器、容器、有洁癖的人什么包都得自己装
Miniforge约 600 MB,默认走 conda-forge团队协作、企业合规场景老教程里的conda install参数需要改
apt 装 python3-venv几百 MB只做纯 Python 小项目、不碰科学计算二进制依赖全靠本地编译

这篇按标题来,走 Anaconda 这条路,最后把 Jupyter Notebook 跑起来,并且把这中间会踩的坑一个个摊开讲。

2. 取包这一步就有人翻车:版本、架构与校验

2.1 安装包名字里藏着三个关键信息

Anaconda 的 Linux 安装包命名格式是Anaconda3-<版本>-<构建号>-<平台>.sh,比如Anaconda3-2024.10-1-Linux-x86_64.sh。拆开看:

  • 2024.10是发行版本,代表打包时的时间点,不是 Python 版本。这个包里可能带 Python 3.12,也可能是 3.11,装完用python -V看才知道。
  • -1是同一版本的第几次构建,出过问题会重打包,所以数字越大通常越稳。
  • Linux-x86_64是 CPU 架构。这一步是 ARM 服务器用户的经典翻车位:在鲲鹏、飞腾、或者树莓派、ARM 云主机上,要的是Linux-aarch64。先跑一句:
uname -m

输出x86_64就下 x86_64 版,输出aarch64就下 aarch64 版。下错了不会立刻报错,而是运行安装脚本时给你一句cannot execute binary file或者干脆卡住,新手很容易以为是系统问题。

2.2 从镜像站取包,顺便把校验做了

官方站点的下载在国内经常几十 KB/s 地爬,换成国内镜像站是常规操作。以清华镜像为例,归档目录是https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/,里面按字母序排着所有历史版本。

cd ~/Downloads wget -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2024.10-1-Linux-x86_64.sh # 如果目录里提供了对应的 .sha256 文件,一并下载 wget -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2024.10-1-Linux-x86_64.sh.sha256 sha256sum -c Anaconda3-2024.10-1-Linux-x86_64.sh.sha256

-c参数是断点续传,网断了重跑一遍命令就行,不用从零开始。校验这一步别省,尤其你是从第三方网盘或者别人转发的链接拿包的时候——安装脚本是要用bash执行的,本质上就是跑一段别人写的 shell,来源不可信风险很高。

提示:镜像站同步有延迟,刚发布的版本可能还没同步过去。看到目录里最新的是两三个月前的版本,不用纠结,挑一个次新的正式版更省事,新版本头几周经常有各种依赖构建的小毛病。

2.3 装之前先看一眼磁盘

Anaconda 解压后加上缓存,峰值能吃掉 6 GB 左右。装之前看一眼:

df -h ~

Avail小于 8 GB 的话,要么先清缓存(sudo apt clean、清掉~/.cache),要么把安装目录放到另一块盘上。我遇到过一次装到一半No space left on device,conda 的目录树处于半残状态,删都删不干净,最后只能rm -rf重来。

3. 安装脚本里的三个提问,分别该怎么答

3.1 交互式安装:每一步在做什么

cd ~/Downloads bash Anaconda3-2024.10-1-Linux-x86_64.sh

回车确认许可协议(要按好几次空格翻页,最后输入yes),然后会问安装路径,默认是/home/<用户名>/anaconda3。

关于路径,我的取舍是这样的:

  • 个人机器:就用默认的$HOME/anaconda3。不需要sudo,以后删起来也干净,rm -rf完事。
  • 多人共用的服务器:装到/opt/anaconda3,用sudo执行。但装完必须把属主改掉,否则普通用户没法往环境里写包:
sudo chown -R $USER:$USER /opt/anaconda3
  • 千万别装到/usr/local/anaconda3或者任何已经在PATH里的系统目录,那是给自己埋雷。

然后脚本会问一句Do you wish the installer to initialize Anaconda3 by running conda init?,答案是yes。这个动作会在~/.bashrc末尾追加一段带# >>> conda initialize >>>标记的 shell 函数。这段代码干的事很简单:定义conda这个 shell 函数,并决定每次开终端要不要自动激活base环境。很多人以为conda是个可执行文件,其实在 bash 里它是个函数,which conda能看到它的定义。

3.2 静默安装:批量部署时的写法

给一批机器装,用-b和-p两个参数跳过所有交互:

bash Anaconda3-2024.10-1-Linux-x86_64.sh -b -p $HOME/anaconda3

注意-b模式下不会执行conda init,必须手动补:

source $HOME/anaconda3/bin/activate conda init bash exec $SHELL -l

这三行的顺序有讲究。第一行只是把当前这个 shell 临时接进 conda;conda init才是把配置写进~/.bashrc;exec $SHELL -l是重新加载一个登录 shell,让配置立刻生效。少了最后一步,你会觉得"明明初始化了,为什么新开终端还是没有conda命令"。

3.3 装完后的四句验证,一句都不能少

conda --version # 例如 conda 24.9.2 conda info # 看 base environment 路径、python 版本、channel 列表 which python # 应该指向 ~/anaconda3/bin/python python -c "import sys; print(sys.executable, sys.version)"

which python这一句是最重要的自检。如果它输出的还是/usr/bin/python,说明PATH优先级不对,你的代码跑的仍然是系统解释器,后面装包会装到系统里去,混乱就是这么开始的。

还有一个我强烈建议装完就做的动作——关掉 base 自动激活:

conda config --set auto_activate_base false

理由很实际:base 环境应该是"干净的调度中心",只用来创建和切换环境。一旦你在 base 里装了几个包(比如为了临时用一下requests),A 包依赖urllib3 1.x、B 包依赖2.x,几个月后 base 就彻底烂了,只能重装。关掉自动激活,终端每次打开默认回到系统 Python,需要时再conda activate,这个习惯能救命。

4. conda 和 pip 双双换源:速度与稳定性的取舍

4.1 conda 的.condarc怎么写

默认状态下 conda 走repo.anaconda.com,国内访问经常超时,Solving environment卡几分钟然后失败。写一份~/.condarc:

channels: - defaults show_channel_urls: true default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 custom_channels: conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud

show_channel_urls: true不是可有可无的装饰。开着它,安装时终端会明确告诉你这个包是从哪个 URL 拉的。排查"为什么同一个包在不同机器上版本不一样"的时候,这一行能省掉半小时。

改完记得清索引缓存,否则 conda 还在用旧的元数据:

conda clean -i conda update -n base conda

4.2 频道混用的坑,比速度问题更值得警惕

defaults和conda-forge是两个独立维护的构建体系。同一个numpy,两边编译时链接的 BLAS 实现可能不一样(一个是 MKL,一个是 OpenBLAS)。混装的后果是运行时import numpy直接段错误,报错信息还看不懂。

conda config --set channel_priority strict

strict的含义是"永远只从频道优先级最高的那个源里找包",宁可装不到也不混。conda 默认是flexible,它的逻辑是"哪个频道有更新的版本就用哪个",在科学计算场景下这个策略很容易坑人。设成 strict 之后偶尔会碰到"想要的包版本找不到",那就换一个环境单独装 conda-forge,而不是在同一环境里妥协。

4.3 pip 的源要单独配,别指望 conda 帮你管

conda 管不到 pip,而 Jupyter 生态里相当一部分扩展只有 PyPI 上有。所以 pip 也要配一次:

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip config set global.trusted-host pypi.tuna.tsinghua.edu.cn pip config list # 确认写入位置,一般在 ~/.config/pip/pip.conf

这里有个隐藏问题值得单独说:which pip和which python必须落在同一个环境里。conda 环境里如果不小心用到了系统的pip(路径类似/usr/bin/pip3),包装到了系统目录,然后python -c "import xxx"找不到,你会怀疑人生。养成习惯:

python -m pip install <包名>

用python -m pip而不是裸pip,能保证 pip 一定是当前解释器对应的那个,这个习惯我保持了很多年。

注意:如果https请求报证书错误(SSL: CERTIFICATE_VERIFY_FAILED),先检查系统时间。虚拟机挂起恢复之后时间跑偏是常见原因,timedatectl status看一眼,不对就sudo apt install systemd-timesyncd打开自动同步。

5. 建一个专供 Jupyter 的环境,而不是往 base 里堆

5.1 环境怎么建、Python 版本怎么选

conda create -n jupyterlab python=3.11 -y conda activate jupyterlab conda env list

为什么是 3.11 而不是最新的 3.13?因为数据科学栈的轮子(wheel)滞后于 Python 新版本发布,3.13 刚出来那阵子,pytorch、lightgbm、xgboost这些包在有的平台上还没有对应的构建,你会被迫从源码编译。稳定优先,选次新的版本号,这是我给所有做数据分析的人的通用建议。真要用新特性,等半年再说。

环境名用jupyterlab而不是conda、py这种泛泛的名字。一台上可能有十几个环境,名字起得像个记号,三个月后你自己都不记得哪个是干什么的。

5.2 Jupyter 到底该装在哪:这是最容易踩的结构性坑

先明确 Jupyter 的架构:Notebook 前端 + Notebook Server + Kernel(内核)。前端和 Server 是一个独立的 Python 程序,内核是另一个进程,它负责真正执行你的代码。两者之间通过 ZeroMQ 通信。

这个结构导致一个非常经典的翻车场景:

在 base 环境里 conda install jupyter notebook 然后 conda activate 一个只装了 pandas 的新环境 jupyter notebook 启动,新建笔记本,写 import pandas ——ModuleNotFoundError

原因不是 pandas 没装,而是笔记本新建时默认用的内核是 base 的 Python,跟着启动 Jupyter 的那个解释器走的。它根本不知道你切到新环境了。

两种正确姿势,按你的使用习惯选:

姿势一:Jupyter 装进目标环境(推荐,个人用最省心)

conda activate jupyterlab conda install -c conda-forge notebook jupyterlab ipykernel -y

以后想给这个环境加包,先conda activate jupyterlab再装,Jupyter 和代码永远在同一个解释器里,不存在内核错位。

姿势二:base 里装一个 Jupyter,让它管所有环境(多环境切换频繁时用)

conda activate jupyterlab conda install ipykernel -y python -m ipykernel install --user --name jupyterlab --display-name "Python (jupyterlab)"

--name是内核的目录名(英文、无空格),--display-name是笔记本菜单里显示的名字,可以带括号和中文。装完的内核定义落在~/.local/share/jupyter/kernels/<name>/kernel.json,内容很简单,就是一个解释器路径加上启动参数:

{ "argv": ["/home/yourname/anaconda3/envs/jupyterlab/bin/python", "-m", "ipykernel_launcher", "-f", "{connection_file}"], "display_name": "Python (jupyterlab)", "language": "python" }

看argv第一项,那就是这个内核真正用的解释器。当你遇到任何"包明明装了却 import 不到"的问题,第一件事就是把这一项和python -c "import sys; print(sys.executable)"的输出对一下,九成的问题当场定位。

用jupyter kernelspec list可以列出所有已注册内核,不再需要的用jupyter kernelspec remove <name>清掉。

6. 从本机访问到局域网访问:Jupyter 的启动与配置

6.1 先跑通最朴素的形态

conda activate jupyterlab jupyter notebook --no-browser

终端会打印一行形如http://localhost:8888/tree?token=一堆十六进制的地址,浏览器打开就行。--no-browser在服务器上是必须的,否则它会尝试调用xdg-open,在没装桌面环境的机器上会报一堆警告。

第一次跑通之后,别急着到处改配置,先把默认行为理解清楚:默认只监听127.0.0.1,默认带 token 认证,默认工作目录是你执行命令时所在的目录。安全默认值其实挺合理。

6.2 生成配置文件并做持久化设置

jupyter notebook --generate-config

这会生成~/.jupyter/jupyter_notebook_config.py(Notebook 7 及更新版本实际读的是同目录下的jupyter_server_config.py,生成的这个文件里通常是ServerApp开头的配置项)。常见的几项:

c.ServerApp.ip = '0.0.0.0' # 监听所有网卡,局域网可访问 c.ServerApp.port = 8888 c.ServerApp.open_browser = False c.ServerApp.root_dir = '/home/yourname/work' c.ServerApp.allow_remote_access = True c.ServerApp.token = '' # 只是为了让下面的密码生效

c.ServerApp.root_dir建议显式写死。不写的话,工作目录跟着你启动命令的cd走,笔记本的相对路径读文件(pd.read_csv('data/x.csv'))在不同目录启动时会找不到文件,这是"昨天还好好的今天就报 FileNotFoundError"的常见原因。

配密码:

jupyter notebook password

它会让你输入两遍,然后把哈希写进~/.jupyter/jupyter_server_config.json。哈希是加盐 SHA1 之类,不是明文,这点可以放心。

6.3 只在内网开放,别裸奔到公网

把ip设成0.0.0.0之后,同网段的任何机器都能访问这个端口。Jupyter 的权限等同于在你机器上执行任意 Python,所以至少做这两件事:

# 只允许内网网段访问 8888 sudo ufw allow from 192.168.1.0/24 to any port 8888 proto tcp sudo ufw status numbered

以及永远保留认证。我见过有人图方便把token和password全清空、ip设成0.0.0.0,放在办公网里跑了一个月,直到某天发现工作目录里多了几个不认识的笔记本。这种暴露方式风险极高,没必要省那几秒钟登录。

6.4 用 systemd 让它开机自启

[Unit] Description=Jupyter Notebook Service After=network.target [Service] Type=simple User=yourname WorkingDirectory=/home/yourname/work ExecStart=/home/yourname/anaconda3/envs/jupyterlab/bin/jupyter notebook Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target

保存到/etc/systemd/system/jupyter.service,然后:

sudo systemctl daemon-reload sudo systemctl enable --now jupyter sudo systemctl status jupyter journalctl -u jupyter -f

ExecStart里写的是环境内的绝对路径,不要依赖 shell 的conda activate——systemd 不读~/.bashrc,任何依赖 shell 初始化的写法都会失败,这是自启类服务最常见的失败原因。日志用journalctl看,别去猜。

7. 打不开、单元格没反应、ImportError:一套分层排查链路

这部分是这篇内容里最值钱的部分。出问题时不要乱试,按层往下走:进程层 → 监听层 → 网络层 → 浏览器层 → 内核层。每一层都有对应的判断命令,能在几分钟内把范围缩到最小。

现象优先怀疑定位命令处理
终端报错退出,没打印 URL包损坏、端口被占jupyter notebook --debug看堆栈最底部那行
终端有 URL,浏览器打不开监听地址/防火墙ss -lntp | grep 8888检查ServerApp.ip与ufw status
页面能开,新建笔记本 404内核未注册jupyter kernelspec list补装ipykernel并注册
单元格显示[*]一直转内核忙/死看终端是否打印 Kernel died重启内核,查内存
重启后仍无输出环境里缺包在单元格里import sys; sys.executable核对内核路径
ImportError: DLL load failed二进制 ABI 不匹配which pip; pip -V统一用python -m pip重装

7.1 "jupyter notebook 打不开"的三种真实成因

第一种:端口被占。终端里没报 URL,或者报的端口是 8889、8890(Jupyter 发现自己找端口时会顺延)。查一下:

ss -lntp | grep -E '8888|8890'

如果是一台机器上开了好几个 Jupyter(比如自己一个、系统服务一个),端口冲突很常见。解决办法不是杀进程,而是明确指定端口:jupyter notebook --port 8899。

第二种:远程访问配置了但被防火墙挡了。服务端ss能看到0.0.0.0:8888在监听,但另一台机器连不上,那就是ufw或者云主机的安全组没放行。云主机的话两层都要检查,很多人在系统里放行了,忘了控制台的安全组。

第三种:token 拼接出错。复制 URL 的时候漏了后面一长串参数,Jupyter 会跳到登录页要求输入密码。如果你压根没设过密码就会卡住。这时候不用慌,直接在终端里重新跑一次jupyter notebook password设一个就行。

7.2 "单元格执行代码没有任何反应"的定位顺序

这个现象太常见了,值得单独拆开讲。

先看笔记本右上角的内核状态圆点。实心圆 +Busy说明内核真的在跑,那八成是你的代码本身在等 IO(比如input()、网络请求超时、循环里没加打印)。空心圆 +Idle但单元格还是[*],说明前端和内核的通信断了,直接 Restart Kernel 重连。

如果反复出现,回终端看 Jupyter 的日志输出,通常会有Kernel died或者Killed。Killed就是被操作系统的 OOM Killer 干掉了:

dmesg -T | tail -30 | grep -i -E 'killed process|out of memory' free -h

处理方式很直接:减小数据分批处理、加--NotebookApp.max_buffer_size之外的思路是控制内存峰值,或者给机器加 swap:

sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile

还有一种容易被忽略的情况:同一个环境里 notebook 是 conda 装的,ipykernel 是 pip 装的(或反过来),版本对不齐,通信协议不匹配。修法是统一来源:

conda activate jupyterlab conda install --force-reinstall ipykernel -y python -m ipykernel install --user --name jupyterlab --display-name "Python (jupyterlab)" --replace

注意最后的--replace,不加的话同名内核会报冲突,你还得先手动 remove。

7.3 关于ImportError: DLL load failed while importing rpds

这个报错你在搜"jupyter notebook 无法运行"的时候一定会看到。先说清楚它的本质:rpds-py是 Jupyter 生态里jupyter-client、referencing依赖的一个库,为了性能用了 Rust 写的扩展(rpds 是 persistent data structures 的缩写)。DLL load failed的意思是Python 找到了这个扩展模块,但加载它依赖的底层二进制时失败了。

这个具体的报错文本(while importing rpds)几乎都出现在 Windows 上,典型诱因是缺Microsoft Visual C++ Redistributable。Linux 上不会看到同样的字样,但同一类问题在 Linux 上会以另一种面貌出现:

  • ImportError: /path/to/_rust.abi3.so: undefined symbol: ...
  • ImportError: libstdc++.so.6: version 'GLIBCXX_3.4.32' not found

第二种在国内的数据科学服务器上出现频率极高,根因是系统的libstdc++版本比 conda 环境里编译所用的旧。修复是先确认 conda 环境里的运行时库优先被加载:

conda activate jupyterlab export LD_LIBRARY_PATH=$CONDA_PREFIX/lib:$LD_LIBRARY_PATH python -c "import rpds; print(rpds.__file__)"

把这个export写进环境的激活脚本里($CONDA_PREFIX/etc/conda/activate.d/下建一个.sh)可以一劳永逸。另外几种情况也值得一并检查:

  • pip 和 python 不是同一个环境:which pip与which python的路径前缀必须一致。
  • 装到一半网络断了,wheel 是残的:python -m pip install --force-reinstall --no-cache-dir rpds-py jupyter-client,--no-cache-dir是重点,不然 pip 会拿缓存里的坏包再装一遍。
  • conda 环境本身损坏:conda install --force-reinstall -c conda-forge jupyter-client,或者干脆新建环境重来,比修快。

7.4 代码自动补齐和 Markdown 目录:Notebook 7 带来的分水岭

这两个需求在搜索结果里出现频率极高,但很多老教程已经过时了。关键前提:如果你装的是 Notebook 7 及以上版本,基于jupyter_contrib_nbextensions的整套扩展(hinterland、toc2 等)都不再工作,因为 Notebook 7 的界面是基于 JupyterLab 组件重写的,nbextensions 那套注入 JS 的机制失效了。

你有两条路:

路线 A:留在老版本,用 nbextensions

conda activate jupyterlab conda install -c conda-forge notebook=6.5.7 -y python -m pip install jupyter_contrib_nbextensions jupyter_nbextensions_configurator jupyter contrib nbextension install --user jupyter nbextensions_configurator enable --user

重启后首页会多一个Nbextensions标签页,勾选:

  • Hinterland:输入时自动弹出补全候选。
  • Table of Contents (2):在左侧生成 Markdown 目录,支持折叠、跟随滚动。

目录扩展的工作原理是抓取#、##、###这些 Markdown 标题,所以你的笔记里得有规范的分级标题它才有的可抓。全是加粗文本的话,目录是空的,这是最常见的"装了扩展但目录不显示"的原因。

路线 B:上 JupyterLab,用新一代扩展

conda activate jupyterlab conda install -c conda-forge jupyterlab -y python -m pip install jupyterlab-lsp jupyter-lsp jupyterlab-toc

JupyterLab 内置了左侧的目录面板(Table of Contents),不用额外装;代码补全用jupyterlab-lsp,需要额外配一个 language server(Python 用python-lsp-server),配好之后体验接近 IDE。我的实际选择是:新项目全用 JupyterLab,只有需要给别人发.ipynb且对方用老版本 Notebook 打开时才切回去。

顺带说一个 Markdown 目录的偷懒写法:在 Notebook 6 + toc2 的环境里,单元格里写[TOC]也会被渲染成目录;但这个语法没有通用性,Notebook 7 和 GitHub 上都不认,别把它写进要分享的文件里。

8. 和 PyCharm、Neovim 联动,以及 Anaconda 的迁移与清理

8.1 PyCharm 指向 conda 环境

很多人是"Jupyter 里探索、PyCharm 里成稿"的工作流。在 PyCharm 里做两件事:

File → Settings → Project → Python Interpreter → Add Interpreter → Conda Environment,选Existing environment,解释器路径填:

/home/yourname/anaconda3/envs/jupyterlab/bin/python

如果 PyCharm 认不出 conda,在Conda executable那一栏填/home/yourname/anaconda3/bin/conda。识别不到的常见原因是 PyCharm 是通过桌面图标启动的,环境变量没继承过来,改成从终端pycharm.sh启动就正常了。

配置好之后有个很实用的收益:PyCharm 里能直接打开.ipynb文件,单元格可以逐个执行,还能借用刚才在 Jupyter 里配置好的内核。同一个环境两边用,不用重复装包。

8.2 Neovim 里跑笔记本:jupytext 是关键中间件

习惯 Neovim 的人不太愿意为了改两个单元格去开浏览器。可行方案是jupytext做双向同步——它能把.ipynb转成带特殊注释的.py文件,改完再同步回.ipynb,两边内容保持一致。

conda activate jupyterlab python -m pip install jupytext # 一次性转换 jupytext --to py:percent demo.ipynb # 双向同步:之后在 nvim 里改 demo.py,保存就会写回 demo.ipynb jupytext --sync demo.ipynb demo.py

py:percent格式用# %%作为单元格分隔符,Neovim 的很多插件(比如发送代码块到终端的那类)都认这个标记,配合一个终端里跑着的 Jupyter 会话,就能实现"编辑器里写、内核里跑"。实际用下来我的感受是:探索阶段老老实实开浏览器,写库代码或者整理成脚本时再用 nvim + jupytext,硬要在编辑器里做可视化数据分析是逆着工具设计的。

8.3 环境导出、迁移与彻底卸载

导出环境,给别人复现或者迁到新机器:

conda activate jupyterlab conda env export --from-history > environment.yml

--from-history这个参数很重要。不加它,导出的 yml 会把所有依赖的精确版本、构建号、平台信息全写进去,几百行,里面还有一堆https://mirrors...的 URL,换台机器直接装不上。加了它只导出你显式安装过的那些包,新机器上conda env create -f environment.yml让 conda 自己解依赖,成功率高得多。

清理缓存,conda 的缓存目录能涨到几个 GB:

conda clean -a -y du -sh ~/anaconda3/pkgs

彻底卸载 Anaconda,分三步,漏一步就会留下"幽灵命令":

# 1. 删主体 rm -rf ~/anaconda3 # 2. 从 ~/.bashrc 里移除 conda 初始化块 # 找到 "# >>> conda initialize >>>" 到 "# <<< conda initialize <<<" 之间的内容删掉 vim ~/.bashrc # 3. 清残留配置 rm -rf ~/.conda ~/.condarc rm -rf ~/.local/share/jupyter/kernels # 只清 conda 环境的 kernelspec rm -rf ~/.jupyter # 如果不想保留 Jupyter 配置和密码

第 2 步是重点。只做第 1 步的话,新开终端会看到bash: /home/you/anaconda3/etc/profile.d/conda.sh: No such file or directory,每次开终端都刷一遍,很烦人。

8.4 几个我踩过之后才记住的细节

最后把一些零碎但实用的经验集中放这里,都是文档上不太会写的:

  • 改环境名前先想清楚。conda 没有"重命名环境"的官方命令,改envs/下的目录名会让kernelspec里的绝对路径失效,笔记本里的内核要重新注册。不如一开始就起好名字。
  • conda install卡在Solving environment超过三分钟,别再等了,按Ctrl+C打断,加-c conda-forge或者把包拆开一个个装。求解器在 channel 混用时会爆炸式变慢,channel_priority: strict能明显缓解。
  • ${CONDA_PREFIX}是你排查问题的好帮手。echo $CONDA_PREFIX显示当前激活环境的根目录,$CONDA_PREFIX/bin/python就是当前环境的解释器。写脚本、配服务、对路径,都用它,比硬编码~/anaconda3/envs/xxx可靠。
  • 笔记本文件不要放进 conda 环境目录里。环境坏了要rm -rf重建的时候,你不想在删环境之前先抢救数据。代码和数据放在~/work之类的独立目录,环境只负责运行时。
  • 定期给base做体检:conda list -n base | wc -l,如果这个数字明显超过刚装完时的量(一千多属于正常,因为你可能用它装过东西),考虑清理。base只留 conda 本身和相关依赖是最稳的状态。

整套流程跑下来,从零到能在浏览器里写第一行代码,顺利的话二十分钟以内。真正花时间的从来不是安装本身,而是装完之后各种"为什么它不认我的包"的路径问题。把which python、sys.executable、kernel.json里那个路径这三样东西在不同场景下反复对齐,你后面遇到的所有 Jupyter 疑难杂症,基本都能自己定位。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询