如果你刚学 Python,估计对 Jupyter 的第一印象是:怎么是个网页?左边一堆文件,右边一个空输入框,老师让你写代码,你好不容易敲了一行print("hello"),按 Shift+Enter,出来了,然后你就开始纠结——为什么新建的文件叫 Untitled2?为什么一个 cell 只输出最后一行?为什么从 Anaconda 里打开 Jupyter 突然没反应?
这些问题其实都不是 Jupyter 难,而是它的使用习惯和普通 IDE 差别太大。这篇教程我会从安装、启动、目录管理、cell 执行机制、日常高频踩坑一路讲到效率习惯,尽量把“别人用了几年才明白”的细节一次性说清楚。
1. 从安装到启动:Jupyter Notebook 的网页版入口到底怎么进
1.1 安装方式:Anaconda 与 pip 二选一怎么选
Jupyter 的全名叫 Jupyter Notebook,早期又叫 IPython Notebook,核心是“浏览器里写代码 + 代码下方直接给输出”。它不是一个孤立的软件,而是一整套基于 Python 的服务。所以安装方式基本有三条路:Anaconda、Miniconda、pip 单独装。
对于绝大多数刚接触数据分析、机器学习的人来说,我建议直接上 Anaconda。原因很简单:它自带 Python、conda 包管理器,而且预装了 Jupyter Notebook、JupyterLab、pandas、numpy 这些常用库。你不用先折腾 Python 环境再一个个装包,装完打开就能跑。下载就直接去 Anaconda 官网,选对应操作系统的 64 位安装包,按提示下一步。
安装时有几个细节要留意:
- 安装路径尽量不要带中文和空格,比如别装到
C:\Program Files\Anaconda3这种带空格的路径,否则后面某些依赖库解析路径容易出幺蛾子。 - 安装过程中会问“Add Anaconda to PATH”,新版默认是不勾选的。我建议不勾选。勾了虽然能在普通 PowerShell 里直接敲
conda,但会把一堆路径塞进系统环境变量,可能跟别的软件冲突。老老实实用开始菜单里的 Anaconda Prompt 就好。 - 如果你已经有完整的 Python 环境,也可以只用
pip install notebook或pip install jupyterlab。这种方案适合已经习惯用 venv/conda 管理环境的人,但新人不推荐,因为缺的依赖比较多,出了问题不好定位。
装完之后怎么验证?打开 Anaconda Prompt,输入:
jupyter --version jupyter notebook --version如果能打印出版本号,说明安装成功。
1.2 启动命令、网页版登录地址与 Token 的来龙去脉
启动 Jupyter Notebook 的命令很简单:
jupyter notebook但很多人卡在“网页弹不出来”或者“没有自动打开浏览器”这一步。其实 Jupyter 的本质是:你在终端启动一个本地服务,浏览器访问这个服务,然后通过浏览器操作内核。启动后终端会显示类似这样的一段信息:
To access the notebook, open this file in a browser: file:///.../nbserver-...-open.html Or copy and paste this URL: http://localhost:8888/tree?token=4f5e0c9d2a6b...这里的http://localhost:8888/tree就是你常听到的“Jupyter 网页版登录入口”。tree表示文件目录管理页,也就是你新建 notebook 时看到的文件列表页面。后面那一长串token=...是第一次访问的临时令牌,相当于一把钥匙。
浏览器没自动打开时,只需要把终端里那一整串带 token 的地址复制进浏览器地址栏回车。如果 token 忘了也没关系,回到终端找,或者干脆设置一个固定密码:
jupyter notebook password按提示输入两遍密码,重启 Jupyter 之后再访问,就直接输用户名和密码,不再需要 token。密码会存在~/.jupyter/jupyter_notebook_config.json里,Windows 下路径通常是C:\Users\<你的用户名>\.jupyter\。
平时常用启动参数我也整理一下:
| 用途 | 命令 |
|---|---|
| 指定端口启动 | jupyter notebook --port=8889 |
| 不自动打开浏览器 | jupyter notebook --no-browser |
| 指定工作目录启动 | jupyter notebook --notebook-dir=D:/project |
| 局域网内提供访问 | jupyter notebook --ip=0.0.0.0 |
--ip=0.0.0.0这个一般不推荐随便开,除非你在公司内网或受控环境里。远程访问时注意防火墙端口,这个平台就不过多展开了。
最后提醒一句:关闭浏览器页面不等于关闭 Jupyter。服务仍然跑在终端后台,占用着 8888 端口。要彻底关闭,回到启动 Jupyter 的那个终端窗口,按Ctrl+C,再按一次y确认。
2. 把 Notebook 开在想要的位置:临时目录与默认存放地址永久修改
2.1 临时指定目录:先 cd 再启动或加 --notebook-dir
很多人装完 Jupyter 之后一直默认在用户目录下新建文件,结果C:\Users\名字下面堆了一堆Untitled1.ipynb、Untitled2.ipynb。数据路径也乱七八糟。其实 Jupyter 的所有文件管理都是围绕“它启动时所在的目录”展开的,你要做的第一件事就是把它开到项目文件夹。
最直接的办法:先在终端进入目标文件夹,再启动 Jupyter。
Windows 下,打开项目文件夹,在资源管理器地址栏输入cmd或powershell并回车,就在当前目录打开了终端;然后执行:
jupyter notebookMac/Linux 下就是:
cd /path/to/project jupyter notebook这样 Jupyter 打开后,文件树里看到的直接就是这个项目的目录,新建 notebook 也会默认保存在这里。
如果你不想每次手动先 cd,也可以加参数一次性指定:
jupyter notebook --notebook-dir=D:/project注意路径里建议用正斜杠/,在 Windows 上也能正常识别。--notebook-dir是临时指定的,只对这一次启动生效,下次启动还是回到默认目录。
2.2 永久修改默认存放地址:配置文件 jupyter_notebook_config.py
如果你不想每次启动都手动带参数,那就一次性把默认目录改成你习惯的位置。
先生成配置文件:
jupyter notebook --generate-config这个命令会在~/.jupyter/目录下生成一个jupyter_notebook_config.py。Windows 用户去C:\Users\<你的用户名>\.jupyter\下找,Mac/Linux 用户去~/.jupyter/下找。
用文本编辑器打开这个文件,找到这一行:
# c.NotebookApp.notebook_dir = ''把注释符#去掉,改成你的目标路径,例如:
c.NotebookApp.notebook_dir = 'D:/JupyterProjects'保存文件,然后重启 Jupyter。重启之后文件树页面的地址栏会显示你新设置的根路径,比如http://localhost:8888/tree/D:/JupyterProjects。
这里有个容易搞混的点:新版 JupyterLab 的配置文件参数名不太一样。如果你打开的是 JupyterLab,需要找的是c.ServerApp.root_dir,而不是c.NotebookApp.notebook_dir。如果你既用 Notebook 又用 Lab,建议两个都设置成同一个路径:
c.NotebookApp.notebook_dir = 'D:/JupyterProjects' c.ServerApp.root_dir = 'D:/JupyterProjects'我遇到过不少“改了配置没生效”的情况,排查顺序是这样的:
- 是不是启动了多个 Jupyter 实例?旧实例还占着 8888 端口,你访问的其实是旧实例。老实例没加载新配置,新实例又因为端口被占而报错。解决办法是全部关掉,或者换个端口验证。
- 配置文件存错了位置?确认修改的是
~/.jupyter/jupyter_notebook_config.py,不是别的副本。 - 路径写错了权限?特别是 Windows 下别把目录设在
C:\Program Files这种需要管理员权限的位置。 - 当前用的 Jupyter Notebook 和 JupyterLab,配置参数名是否对应。
2.3 移动已有 Notebook 文件与新建时保存位置
你可能会遇到一个旧 notebook 已经躺在别的文件夹里,想把它移到新目录。直接文件系统里移动.ipynb文件就行,Jupyter 对它没有“必须从哪里打开”的限制。但注意一个坑:notebook 里的相对路径是相对于当前工作目录的,不是相对于.ipynb文件所在位置。
比如你原来在D:/old里执行pd.read_csv('data.csv'),没问题;把 notebook 移到D:/project之后,data 文件还在D:/old/data.csv,继续用data.csv就会找不到。移动文件后最好在 notebook 里跑一下%pwd确认当前目录,再补上路径。
新建 notebook 时想存到别的文件夹?很简单:在文件树页面先点进目标文件夹,然后点右上角New,选择 Python 3 内核,新建的 notebook 就默认保存在当前文件夹里。保存之前给它改个有意义的名字,避免都叫 Untitled。
3. 搞懂 Cell 的执行规则:为什么只显示最后一行,以及怎么查看执行进度
3.1 输入输出机制:最后一个表达式决定 Out
Jupyter 的核心结构是 cell,也就是单元格。一个 cell 可以是一段代码,也可以是一段 Markdown 文字。代码 cell 被执行时,整段代码会被发给内核,内核执行完,输出显示在该 cell 下方。
很多人第一次碰到“一个 cell 只输出最后一行结果”,先怀疑是不是自己代码写错了。其实这是 IPython 的 REPL 特性。看个例子:
print("第一行输出") 1 + 1 2 + 3这个 cell 运行后,输出区会是这样:
第一行输出 Out[1]: 5为什么会显示5而不是2?因为对于一个代码 cell,IPython 只会把“最后一个表达式的值”作为Out[n]展示出来。print("第一行输出")是标准输出,不算表达式结果;1 + 1是倒数第二个表达式,被吞掉了;最后一个表达式2 + 3的值是 5,于是显示 5。
再看一个更实际的情况:
a = 10 b = 20 a + b输出只有Out:30。这很正常,Jupyter 不会把前面的a = 10、b = 20都显示出来,因为它们在 Python 语义里只是赋值语句,没有产生可在 REPL 中展示的表达式值。
想一次性看多个结果,最朴素的做法是用 print:
print(a + b) print(a * b)这样不管有多少个 print,都会按顺序显示。
3.2 多个结果展示与抑制输出
除了 print,更推荐用 IPython 自带的display函数,尤其是处理图片、DataFrame、Markdown 这些富内容时:
from IPython.display import display x = 1 y = 2 display(x) display(y)输出区会依次显示1和2,每个对象都占一个独立输出块。和 print 不同,display 能保留对象的富文本展示形式,比如 DataFrame 的表格样式、matplotlib 的图片对象。
还有一个高频技巧:画图时不想让 cell 输出一堆[<matplotlib.lines.Line2D at 0x...>]文本,只需要在最后一个绘图语句后面加英文分号:
import matplotlib.pyplot as plt plt.plot([1, 2, 3], [1, 4, 9]);分号的作用是隐藏该表达式的返回值。图形照常显示,但 cell 不会新增一行多余的 Out 文本。这个小操作能让演示 Notebook 看起来干净很多。
3.3 查看执行进度的几种手段
执行进度怎么查?Jupyter 没有一个显眼的“绿色滚动条”告诉你跑了百分之多少,但你有很多间接信号。
第一个信号是 cell 左侧的In[]标记。运行中的 cell 会显示成In[*],执行完成后变成In[12]这样带编号的样式。编号从 1 开始递增,表示你这是第几个执行过的 cell。如果看到某个 cell 一直停在In[*],说明它还在跑。
第二个信号是菜单栏右侧的内核状态图标。空闲时显示空心圆,忙时显示实心圆,鼠标悬停会看到 “Kernel Busy / Idle” 字样。另外工具栏上也有方形停止按钮和圆形重启按钮,停止按钮用来中断当前运行,重启按钮会杀掉内核重来,变量会全部清空。
如果你要精确测量代码执行时间,用魔法命令:
%%time sum = 0 for i in range(1000000): sum += i%%time放在 cell 第一行,整个 cell 执行完会打印 CPU 时间和 Wall time。如果只测一行,用%timeit会做多次测试,更适合微基准测试。
循环里要看进度条,装一个 tqdm 就能解决:
from tqdm.auto import tqdm for i in tqdm(range(10000)): pass执行时会在 cell 输出区出现一个动态进度条,带预计剩余时间。这个在跑模型训练、批量数据处理时非常有用。不要裸跑一个几万次的循环然后干等,加个进度条比什么都强。
4. 高频问题排查:Anaconda 打不开、复制粘贴失灵、Untitled2 重命名
4.1 Anaconda 里的 Jupyter 突然打不开,从哪里开始查
“Anaconda 里的 Jupyter 突然用不了了”可能是所有初学 Python 的人都会遇到的一次噩梦。常见症状是:Anaconda Navigator 里点 Launch,转圈半天,浏览器没反应;或者直接双击 Jupyter Notebook 图标,没有任何窗口弹出。
我的排查顺序基本固定:
第一步,绕过 Anaconda Navigator,直接打开 Anaconda Prompt,手动执行:
jupyter notebook这样做的目的是让错误信息直接打到终端窗口里。Navigator 会封装错误,反而让你看不到真正原因。
第二步,看终端是否报端口占用。比如显示:
[Errno 10013] ... 或者 [Errno 98] Address already in use说明 8888 端口被另一个 Jupyter 进程占了。很可能你之前关掉了浏览器,但终端服务并没有关掉。解决办法是换端口启动:
jupyter notebook --port=8890也可以用jupyter notebook list查看当前正在运行的 notebook 服务,根据提示决定关掉还是换端口。
第三步,如果端口没问题但还是一直打不开,怀疑配置文件损坏。最简单的处理是重命名.jupyter目录,让 Jupyter 重新生成默认配置:
mv ~/.jupyter ~/.jupyter_backupWindows 用户直接把C:\Users\<用户名>\.jupyter改名为.jupyter_backup。之前设置的密码和自定义参数会失效,但至少能恢复启动。确认没问题后再把备份里的配置文件挑出来恢复。
第四步,如果网页能打开,但新建 Notebook 时提示 Kernel Error 或内核一直连不上。这种情况多半是 ipykernel 与当前 Python 环境不匹配。执行:
conda install ipykernel --update-deps或者:
pip install --upgrade ipykernel jupyter_client之后重启 Jupyter 验证。
还有一个很琐碎但常见的坑:系统里既有 Anaconda,又有 Windows Store 或官网安装的 Python,导致 PowerShell 里敲jupyter指向了另一个路径。用where jupyter(Windows)或which jupyter(Mac/Linux)看一下,如果路径不在 Anaconda 目录下,就换 Anaconda Prompt 操作。
4.2 复制粘贴的正确姿势与缩进坑
“打代码时怎么复制粘贴 Jupyter”听上去像新手问题,但实际坑很多。
从外部网页、PDF、Word 复制代码粘贴到 Jupyter cell 时,经常出现这些状况:
- 中文引号混进代码,报
SyntaxError: invalid character - 缩进全变成空格,且层级错乱
- 换行丢失,一行代码变成一根长面条
- 粘贴后莫名其妙多出缩进,导致
IndentationError
有效的处理办法是:先把代码粘贴到记事本或 VS Code,观察一遍内容是否干净,再复制进 Jupyter cell。这一步等于帮你去掉富文本格式。粘贴到 Jupyter 时,推荐用Ctrl+Shift+V(Mac 用Command+Shift+V)进行无格式粘贴,避免浏览器带上样式。
如果你要复制整个 cell,而不是 cell 里面的几行文字,那就要用命令模式。先按Esc让 cell 退出编辑状态,这时 cell 边框变成命令模式样式。然后按键:
C复制当前 cellV将复制的 cell 粘贴到当前 cell 下方Shift+V将复制的 cell 粘贴到当前 cell 上方
注意,在编辑模式里按C只是输入字母 C,这就是为什么很多新手觉得快捷键失灵。先按 Esc,再按字母键,顺序不能反。
从浏览器外部粘贴代码到 cell 时,如果发现粘贴后 Tab 缩进失效,还有一个土办法:先粘贴到一个新建的 Markdown cell,再从 Markdown cell 里复制到代码 cell。因为 Markdown cell 会保留纯文本结构,往往能过滤掉不少格式问题。虽然绕,但能救命。
4.3 重命名 Untitled 文件与自动保存机制
文件树里那些Untitled.ipynb、Untitled1、Untitled2是 Jupyter 按顺序生成的默认名。Untitled2不代表它经历了什么奇怪的事,只是当前目录下已经存在Untitled和Untitled1,系统自动跳到下一个编号。
重命名有两种方式:
- 在文件树页面,单击文件名称,点击上面工具栏的 Rename 按钮,输入新名称。
- 在 notebook 内部,按
Esc进入命令模式,按R,输入新名称并回车。
建议一拿到文件就重命名。不然多个 Untitled 混在一起,再想找回哪个是哪个,真的很痛苦。
关于保存,Jupyter 有自动保存和 checkpoints 机制。默认会在你操作过程中自动做检查点保存。如果想要保险,可以经常手动Ctrl+S。如果误删了内容,可以在菜单File -> Revert to Checkpoint里选择历史版本恢复。注意 checkpoint 保存的是.ipynb的快照,不是你data.csv、模型文件这些外部数据,所以数据和代码还是得靠 Git 或网盘这类外部版本管理。
5. 让 Jupyter 效率明显提升的几个习惯
5.1 命令模式与快捷键:先分清再记忆
很多人用 Jupyter 半年还在全程鼠标点点点,效率不可谓不低。Jupyter 的 cell 有两种模式:编辑模式和命令模式。
- 编辑模式:正在输入代码,光标在 cell 里闪烁,边框一般是绿的或蓝色高亮。
- 命令模式:光标不在 cell 里,cell 只有一个外边框,此时按字母键会被解释为快捷键。
新手搞不清这两种模式,就会发生“按 B 没插入新 cell 而是打了一个 b”的情况。所以先形成肌肉记忆:写完代码,先按Esc,再按快捷键。
常用快捷键列表:
| 功能 | 快捷键 |
|---|---|
| 运行当前 cell,并跳转到下一个 cell | Shift+Enter |
| 运行当前 cell,光标留在原处 | Ctrl+Enter |
| 运行当前 cell,并在下方插入新 cell | Alt+Enter |
| 在上方插入 cell | A |
| 在下方插入 cell | B |
| 删除当前 cell | D 按两次 |
| 当前 cell 转为 Markdown | M |
| 当前 cell 转为代码 | Y |
| 保存 notebook | Ctrl+S |
| 查找替换 | F |
| 命令面板 | Ctrl+Shift+P |
Mac 用户把 Ctrl 换成 Command,不过 Shift+Enter 这几个键基本一致。
5.2 魔法命令与 Markdown cell 的配合
Jupyter 底层是 IPython,所以支持大量魔法命令。刚开始不需要全背,但这几个能显著提升体验:
%pwd查看当前工作目录。看到它,你就能理解很多“读不到文件”的问题。
%cd /path/to/folder切换当前工作目录。注意这个目录切换只对当前 notebook 的内核有效,不会改 Jupyter 的根目录。
%ls列出当前目录文件。调试找不到数据文件时非常好用。
%matplotlib inline让 matplotlib 输出直接嵌入 Notebook,旧版本尤其需要这一句。新版本 Notebook 默认可视,但写上无害。
%%time放在 cell 顶部,显示整个 cell 的运行时间。
%run xxx.py运行一个外部 Python 脚本,并把它产生的变量导入当前命名空间。
Markdown cell 也是 Jupyter 的精华。切换成 Markdown 之后,你可以写标题、写说明,甚至写 LaTeX 公式。比如第一个 cell 用来描述项目背景,第二个 cell 用来导入库,第三个 cell 设置全局参数,后面才是数据处理。这种结构让 notebook 不只是一段滚动代码,更像一份可执行的报告。
5.3 保存、导出与清理输出
分享 notebook 给别人,或者提交到 Git 之前,建议做一次清理:菜单Kernel -> Restart & Clear Output,然后Ctrl+S保存。这样.ipynb文件体积会小很多,别人打开时也不会看到一堆辣眼睛的报错输出。当然,如果你要展示给老板看分析结果,那就保留输出。
导出成 Python 脚本,命令行比菜单更稳定:
jupyter nbconvert --to script notebook.ipynb会生成一个notebook.py,里面包含所有代码 cell,Markdown 变成注释。这在要把 Notebook 里的逻辑整合进正式项目时很有用。
再提一个长期养生习惯:每个项目单独开一个 conda 环境。Jupyter 里运行的 Python 是当前环境里的 Python,如果你在 base 环境装了一堆包,某天升级 Anaconda 后所有包全乱,是很常见的事。项目建独立环境时:
conda create -n myproject python=3.11 conda activate myproject pip install jupyter notebook pandas matplotlib jupyter notebook这样环境之间互不干扰,某个项目的包坏了,重建环境就行,不至于牵连其他工作。
Jupyter 我用了快五年,真正让我觉得顺手起来的关键不是某个高级插件,而是把默认路径固定下来、搞懂 cell 的输出机制、养成“写完就保存并规范命名”的习惯。这几个点看起来小,但每一项都能帮你少踩几个坑。希望这篇能让你在下一次新建 notebook 时,直接落在正确目录里,而不是又开一个 Untitled3。