Jupyter Notebook 基础操作与常见报错排查指南 📅 2026/8/26 4:58:19 如果你刚开始学 Python多半会遇到一个很真实的困扰在命令行里写代码代码一多就想回头改但前面的输出早就刷走了换到 IDE 里写脚本又为了看一步中间结果不得不上上下下加一堆print。数据稍微复杂一点整个人就陷入“改代码—重跑—看输出—再改”的循环里。Jupyter 这类工具最初就是为了打断这个循环而出现的。我的判断是Jupyter 不是简单的“网页版 Python 编辑器”它本质上是一套以“单元格”为最小执行单位的计算笔记工作流。它真正改变的不是你写代码的方式而是你检查代码、组织思路、逐步验证的方式。它特别适合数据分析、算法调试、教学演示、论文复现这类需要反复试错的场景但它也像一把过分锋利的小刀不适合用来维护大型工程代码。很多新手把 Jupyter 当成记事本用其实是用错了它的核心能力。这篇文章会完整覆盖 Jupyter 代码与基础操作从安装启动、目录切换、单元格执行模型、常用魔法命令到 Notebook 与 Lab 怎么选再讲 Windows 下常见的“不是内部或外部命令”“启动失败”“打开空白”等报错修复思路最后给出工程化使用建议。读完你不仅能跑通环境还能避开新手最常见的那些坑。1. Jupyter 到底是什么先建立正确的认知框架1.1 从 IPython Notebook 到 JupyterJupyter 的前身是 IPython Notebook。IPython 本身是一个增强版 Python 交互式解释器后来团队把 Notebook 从 IPython 中分离出来形成了独立的 Jupyter 项目。2014 年之后Jupyter 开始支持多种编程语言内核不只是 Python还包括 R、Julia 等“Jupyter”这个名字就取自这三种核心语言的字母组合Julia、Python、R。所以 Jupyter 严格来说不是一个 Python 库而是一个跨语言的计算交互协议和前端工具。Python 只是它最常见的落点。1.2 核心概念单元格、内核、会话要真正理解 Jupyter你只需要搞懂三个词单元格CellNotebook 里每一块可独立执行的代码块或文本块。写代码的单位不是“整个文件”而是“一个格子”。内核Kernel真正执行代码的 Python 进程。Notebook 编辑区只是前端壳代码发给内核执行结果再传回前端显示。会话Session一次内核持续运行的过程。内核里的变量、模块、状态会一直保留直到你手动重启内核或关闭文件。这里最容易被误解的是Notebook 的代码不是按“从上到下”被完整执行的而是按你逐个单元格的运行顺序执行的。这一点后面会专门展开。1.3 .ipynb 文件到底是什么Jupyter Notebook 保存的文件后缀是.ipynb。从工程上讲它本质是一个 JSON 文件。你可以用任意文本编辑器打开它里面记录了每个单元格的输入代码、输出结果、执行次数、Markdown 文本等。举一个最小示例hello.ipynb打开后大概是这样的结构{ cells: [ { cell_type: code, execution_count: 1, metadata: {}, source: [print(hello jupyter)], outputs: [ { name: stdout, output_type: stream, text: [hello jupyter\n] } ] } ], nbformat: 4, nbformat_minor: 5 }这个结构意味着两件事.ipynb不是纯文本脚本不能直接被 Python 解释器执行。它天然适合用 Git 做版本管理但合并冲突时会比较痛苦因为输出内容也会被记录进去。理解了这个文件结构后面“如何导出 .py 文件”“如何清理输出再提交 Git”就都说得通了。1.4 Jupyter 适合谁不适合谁从实际使用看Jupyter 最适合四类人数据分析和机器学习从业者探索数据时每一步可视化都直接显示在输出区非常流畅。算法和论文复现者可以按照“读数据—清洗—建模—评估”的顺序逐步运行状态保留。教学场景 Markdown 和代码混排本身就是天然的实验讲义。日常写小工具的人比命令行脚本更直观比 GUI 程序更轻。Jupyter 不太适合的场景是大型工程系统、需要严格模块化组织的生产代码、需要长时间稳定运行的服务。这时候更建议把逻辑写成.py模块再放进正规的 IDE 工程中管理。2. 环境准备安装 Jupyter Notebook / Jupyter Lab安装 Jupyter 的方式主流有三种。对新手来说我推荐第一种。2.1 方式一通过 Anaconda 安装推荐Anaconda 是一个 Python 发行版里面自带了 conda 包管理器、Python 解释器、Jupyter Notebook、Spyder 等工具。安装 Anaconda 之后Jupyter 基本就是开箱即用的。在 Anaconda Prompt 中输入jupyter notebook就能启动 Notbook。Anaconda 的好处是自带 Python 和常用数据科学库省去装库踩坑。conda 可以创建隔离环境解决依赖冲突。Jupyter 与 Anaconda 的集成度最高。缺点是安装包体积大、启动慢。如果你已经熟悉 Python 环境管理可以跳过 Anaconda。2.2 方式二pip 安装如果你已经有 Python 环境可以直接用 pip 安装pip install jupyter notebook或者只装 JupyterLabpip install jupyterlab安装完成后启动 Notebookjupyter notebook启动 Labjupyter lab这里最容易出问题的地方是jupyter命令找不到通常是因为 Python 的 Scripts 目录没有加入系统 PATH或者没有激活对应的虚拟环境。具体排查方法我放到第 7 章。2.3 方式三conda 单独创建环境如果你是 conda 用户更推荐单独建一个环境不要污染 base 环境conda create -n jupyter-demo python3.9 conda activate jupyter-demo pip install jupyter notebook注意这里的 Python 版本、包版本请以你本机实际安装为准。重点在于“独立环境安装”这个思路它可以避免不同项目依赖互相干扰。启动后浏览器会自动打开一个页面。如果没打开终端里会显示类似http://localhost:8888/tree的地址手动复制到浏览器即可。2.4 基础启动参数Jupyter Notebook 支持不少启动参数新手先掌握三个就够# 指定端口启动 jupyter notebook --port 8888 # 指定工作目录启动 jupyter notebook --notebook-dir/Users/zhang/data-project # 启动但不自动打开浏览器 jupyter notebook --no-browser--notebook-dir特别重要。很多人打开 Jupyter 后看不到自己的项目文件就是因为默认目录和项目目录不一致。把这个参数记下来能省去很多“切目录”的烦恼。3. 第一个 Notebook从启动到运行3.1 新建一个 Notebook启动 Jupyter Notebook 后页面右上角有一个New按钮在下拉菜单中选择 Python 3就会创建一个新的 Notebook。创建成功后你会看到一个空页面上面是一个输入框这就是一个单元格。在单元格里输入print(hello, jupyter)然后按Shift Enter代码就会执行输出会显示在单元格下方。这一步是整个 Jupyter 中最核心、最常用的操作。3.2 单元格的两种主流类型Jupyter 的单元格主要分两类Code 单元格写 Python 代码并执行。Markdown 单元格写文档、公式、说明文字按Shift Enter渲染成排版好的文本。切换单元格类型有两种方式菜单栏选择Cell Cell Type。使用快捷键选中单元格后按Esc退出编辑模式再按Y切换为 Code按M切换为 Markdown。Markdown 单元格是 Jupyter 区别于普通脚本的重要特性它让“代码和说明放在一起”成为可能。写一个简单示例# 这是标题 这里可以写**加粗文字**、行内代码还可以写公式 $$E mc^2$$3.3 掌握常用快捷键快捷键决定了你在 Jupyter 里的操作效率。核心快捷键如下操作快捷键运行当前单元格并进入下一个单元格Shift Enter运行当前单元格并停留在原地Ctrl Enter进入编辑模式Enter退出编辑模式Esc将单元格切换为 MarkdownEsc 后按 M将单元格切换为 CodeEsc 后按 Y在上方插入单元格Esc 后按 A在下方插入单元格Esc 后按 B删除当前单元格Esc 后连续按两次 D保存当前 NotebookCtrl S初学者不用一下子全记住先把Shift Enter、A、B、D D这四个练熟效率就会明显提升。3.4 Notebook 的保存机制Notebook 默认会自动保存也会在页面显示“最后检查点”时间。如果你想手动创建版本检查点可以点击菜单栏的File Save and Checkpoint。这相当于给当前代码状态拍一张快照之后可以回到这个版本。4. 单元格执行模型新手最容易踩坑的地方Jupyter 看起来像普通编辑器但它的执行模型和“从头到尾运行整个脚本”完全不同。不搞清楚这一点代码报错时你会非常困惑。4.1 变量和状态是跨单元格共享的在 Jupyter 中同一个内核里的变量会全局共享。举个例子我在第一个单元格写入# 单元格 1 a 10 print(a , a)按Shift Enter运行后a就保存在内核里了。接着我在第二个单元格里写# 单元格 2 b a * 2 print(b , b)再运行输出会是20。这说明b能直接使用a的值不需要重新定义。这个特性很强大它让你可以分步执行长流程。但也是一个巨大的隐患如果你跳过了单元格 1直接运行单元格 2就会触发NameError: name a is not defined这相当于脚本缺失了前半段。4.2 执行顺序不等于“从上到下”Notebook 允许你任意跳着执行单元格。例如你可以先运行第 5 个单元格再回来运行第 2 个单元格。界面左侧的In [1]、In [2]编号就代表执行顺序而不是文件行号。这意味着你最后看到的变量值不一定是你看到的那段代码逻辑产生的。如果你先运行了单元格 A修改了某个变量再回去执行单元格 BB 看到的就是 A 改完之后的状态。举个例子# 单元格 3 status pending print(status)# 单元格 4 status finished print(status)如果你先运行 4再运行 3最后运行 4最终状态仍然是finished。但如果你中途好奇运行了一下 3状态又变回pending。这种“状态漂移”是 Jupyter 里最隐蔽的 bug 来源。4.3 什么时候必须重启内核当你发现自己试了很多次代码逻辑没错但结果始终不对时大概率是内核状态已经乱了。这时候不要急着删单元格先执行Kernel Restart Run All这个操作会清空所有变量和内存状态然后按照单元格从上到下的顺序重新执行一遍完整代码。这也是验证 Notebook 是否可复现的黄金标准。我的建议是每次把 Notebook 交给别人之前或者从仓库拉下来准备运行之前先执行一遍 Restart Run All。如果它能顺利跑通说明代码顺序是自洽的如果中途报错说明你的 Notebook 依赖了某些“之前手动运行过但后来删掉”的变量。4.4 异常处理单元格运行出错时Notebook 会显示完整的 traceback。很多人在这里犯的一个错误是只盯着最下面一行错误信息看忽略上面的调用栈。正确的做法是先看错误类型是NameError、TypeError还是KeyError。再看 traceback 中指向你代码的那一行找到具体出错位置。如果是变量未定义先往前找它是不是在某次执行前才定义的并检查你是否跳过了某个单元格。5. 在 Notebook 中管理代码魔法命令与基础操作除了常规 Python 代码Jupyter 还内置了一批“魔法命令”。它们是 Jupyter 基础操作里非常实用、但新手往往不知道的一部分。5.1 用 %timeit 和 %%time 评估性能在代码分析时我们经常想知道一段代码跑了多久。%timeit会多次运行单行代码给出更稳定的平均耗时%timeit sum(range(1000000))%%time是单元格级魔法命令放在单元格第一行统计整个单元格的运行时间%%time total 0 for i in range(1000000): total i print(total)输出会显示 CPU times 和 Wall time。通过这两个命令你可以快速判断不同写法之间的性能差异。5.2 用 %run 运行外部脚本Jupyter 里可以直接运行一个.py文件等价于在命令行执行python xxx.py%run demo_script.py如果脚本里定义过函数或变量运行之后它们也会留在当前内核中你可以继续在单元格里调用。5.3 用 %%writefile 把单元格内容写成 .py 文件很多新手纠结“Jupyter 怎么创建 .py 文件”。其实不需要额外操作在单元格里用魔法命令即可%%writefile demo_script.py def greet(name): return fHello, {name} if __name__ __main__: print(greet(Jupyter))运行后当前目录下就会生成demo_script.py。然后用%run执行它%run demo_script.py输出Hello, Jupyter这个操作适用于你已经在 Notebook 里把逻辑调试好了想把它转成独立脚本提交到项目中。5.4 用 %matplotlib inline 显示图表在 Jupyter 里画图新手最容易遇到的问题就是plt.show()不显示或者弹出一个无响应窗口。解决办法是在 Notebook 开头加一行%matplotlib inline然后正常使用 matplotlibimport matplotlib.pyplot as plt x [1, 2, 3, 4] y [x_i ** 2 for x_i in x] plt.plot(x, y) plt.title(Square) plt.show()%matplotlib inline会让图表直接嵌入到 Notbook 输出区不用额外弹窗。这是数据分析场景下最常用的基础配置之一。5.5 其他值得知道的魔法命令命令作用示例%who查看当前内核中定义的全部变量%who%env查看或设置环境变量%env MY_KEYvalue%ls列出当前目录文件类似命令行 ls%ls%reset清空所有变量%reset -f%debug在异常后进入调试器先制造一个异常再执行%debug这些命令都不算高深但在日常操作中使用频率很高。尤其是%who当你忘记自己定义了哪些变量时它比翻代码更高效。6. Jupyter Notebook 和 Jupyter Lab 到底选哪个Jupyter Lab 是 Jupyter 官方推出的下一代交互式界面。它不是一个完全独立的产品更像是 Notebook 的“升级版工作台”。两者的核心内核、文件格式、代码执行机制都是一样的区别主要在前端交互和组织方式。6.1 功能对比对比维度Jupyter NotebookJupyter Lab定位单文档编辑器多任务 IDE 风格工作台多标签页支持有限支持且可自由拖拽布局文件管理无内置文件浏览器有内置文件浏览器内置终端无有终端可同时使用 Shell插件体系Notebook 扩展配置麻烦Lab 扩展可视化安装CSV/图片预览需要额外操作双击直接预览适合场景简洁笔记、教学演示多文件项目、日常开发从实际选择来看如果你只是写单个 Notebook或者用 GitHub 上别人分享的.ipynb做阅读和学习经典 Notebook 界面足够。如果你需要一边写代码、一边查看数据文件、一边开终端跑命令Jupyter Lab 更顺手。如果机器性能一般经典 Notebook 更轻量Lab 因为前端更重启动和操作会稍慢。6.2 在 Jupyter Lab 中切换目录在 Lab 里切换目录比在经典 Notebook 中简单得多左边文件浏览器直接列出了当前工作目录你可以双击进入任意子目录或者在右键菜单中选择Open in New Notebook。如果启动时目录不对建议先退出重新用jupyter lab --notebook-dir/你的目标目录启动。这个方式最干净比在环境中到处os.chdir()更不容易出错。6.3 Notebook 里能不能用 os.chdir 切换目录技术上可以import os os.chdir(/path/to/project)但我不推荐在 Notebook 中依赖它。原因是切换目录只作用于当前内核如果将来你重启内核这行代码不会自动执行后续所有读取文件的相对路径都会失效。更稳妥的方式是在启动时通过--notebook-dir指定根目录然后在 Notebook 内使用相对路径。7. 常见问题与排查方法Jupyter 在 Windows、macOS、Linux 上都会遇到一些问题。这里整理的是搜索热度最高的几类也是我观察到新手问得最多的。问题现象可能原因排查方式解决方案jupyter 不是内部或外部命令也不是可运行的程序Python Scripts 目录未加入 PATH或 conda 环境未激活运行where python查看 Python 路径运行python -m jupyter --version验证包是否安装激活虚拟环境或用python -m jupyter notebook启动启动失败报错 Code 2Python 环境路径错乱依赖包缺失不要只看 Exit code向上翻 traceback 定位真实错误尝试python -m notebook重新安装 Jupyter检查 PATH 中的 Python 路径Windows 下 Notebook 打开后空白页面浏览器兼容问题或浏览器代理/扩展冲突换一个浏览器访问http://localhost:8888F12 打开开发者工具看控制台报错清除浏览器缓存禁用相关扩展改用--no-browser后手动访问Notebook 无法自动打开浏览器浏览器关联设置异常终端启动时看是否输出 localhost 地址复制地址到任意浏览器或设置系统默认浏览器怎么让 Notebook 在指定浏览器打开Jupyter 默认调用系统浏览器使用--browser参数指定浏览器路径jupyter notebook --browserchrome或用 Jupyter 配置文件固定如何切换工作目录启动时未指定目录启动终端里执行pwd确认当前路径用--notebook-dir启动或先 cd 到目标目录再执行jupyter notebook如何创建 .py 文件不熟悉 Jupyter 的导出功能和 %%writefile尝试File Download As Python (.py)直接使用%%writefile xxx.py保存当前单元格在 PyCharm 中如何使用 Jupyter不知道 PyCharm 自带集成准备一个.ipynb文件用 PyCharm Professional 打开在 PyCharm 设置中配置 Jupyter server或在编辑器里直接运行单元格7.1 关于jupyter 不是内部或外部命令的补充这个问题在 Windows 上出现频率最高。最直接的原因通常是你安装 Python 时没有勾选 “Add Python to PATH”或者你安装的是 Anaconda但没有在 Anaconda Prompt 中启动 Jupyter。如果你是 conda 用户在 Anaconda Prompt 输入python -m ipykernel install --user然后再启动 Jupyter通常能解决内核识别问题。如果你用了虚拟环境执行命令前先确认已经激活环境conda activate your-env jupyter notebook7.2 Notebook 打开后空白的通用排查顺序在 Windows 上遇到空白页先按这个顺序排查刷新页面。换浏览器访问。清空浏览器缓存。关闭浏览器插件。用无痕模式打开。在终端重新启动jupyter notebook --no-browser把输出里的 token 带进 URL 访问。如果以上都不行再去检查 Jupyter 版本和浏览器版本是否过旧。8. 最佳实践与工程建议把 Jupyter 用顺手和把它用到“可维护、可交付、不出事故”是两回事。下面这些建议是我认为 Jupyter 使用中最值得养成的习惯。8.1 给 Notebook 文件命名命名建议使用英文小写 下划线例如eda_customer_churn.ipynb避免使用空格和中文。原因不是代码会报错而是后续用命令行处理、接入 Git、部署自动化流程时文件名里的特殊字符会带来额外转义成本。8.2 控制单元格的粒度一个单元格不要塞满一百行代码也不要一行写一个单元格。比较好的标准是一个单元格只完成一个相对完整的小步骤例如“读取数据”“清洗缺失值”“训练模型”“评估结果”。这样执行顺序清晰、排错简单、别人阅读时也能快速定位。8.3 使用 Restart Run All 保证可复现交付任何 Notebook 之前至少在本地执行一次Kernel Restart Run All。这一步能验证你的代码是否按从上到下的顺序就能跑通不依赖中途手动运行的隐藏状态。如果中途报错要么调整单元格顺序要么把缺失的逻辑补进去。8.4 提交 Git 前清理输出.ipynb会记录所有输出内容和执行编号提交 Git 时这些内容会产生大量无意义的 diff。建议在提交前清理不需要的输出。删除调试用的临时单元格。有条件的话用jupyter nbconvert --clear-output一键清理jupyter nbconvert --clear-output your_notebook.ipynb这在团队协作中能省去很多不必要的冲突。8.5 不要在生产环境长期依赖 NotebookJupyter 适合做探索、验证和报告但不适合作为生产调度任务的载体。完善的工程化做法是在 Notebook 里完成算法验证后把核心逻辑提取到.py模块再用统一的任务调度平台运行。Notebook 可以保留为分析文档但不要让线上定时任务直接依赖一份.ipynb。8.6 注意安全边界Jupyter 会提供 Web 访问能力。如果你在服务器上打开了 Jupyter请务必注意不要使用默认的--ip0.0.0.0直接暴露公网除非你设置了强密码和 HTTPS。不要随意执行来源不明的 Notebook 代码.ipynb本质上可以包含任意可执行逻辑类似于运行一个.py脚本。离开时及时关闭 URL或设置访问 Token。9. 总结与后续学习方向这篇文章帮你把 Jupyter 代码与基础操作串了一遍它解决了“逐步验证代码记录思路”的痛点核心机制是单元格与内核的交互真正要掌握的不是哪一个图形按钮而是执行顺序、状态管理、魔法命令和可复现性这几个基础概念。如果你刚开始接触 Jupyter接下来最值得做的不是猛学快捷键而是找一个你手头真实的小项目比如分析一份表格数据、画一张图强迫自己在 Notebook 里完成它。过程中把Shift Enter、Markdown 单元格、%matplotlib inline这几样用熟你就能感受到它和普通脚本编写的差别。之后你可以往三个方向深入一是学习用 nbconvert 把 Notebook 导出成 HTML、PDF、Slide 演示文稿适合做技术分享二是研究 Jupyter 的 ipykernel 机制学会把远程服务器或 Docker 容器里的内核接入本地 Jupyter三是了解基于 Jupyter 的 JupyterHub 部署方案这类知识在团队协作工具里非常实用。如果你在读这篇文章的过程中遇到过其他莫名其妙的 Jupyter 报错建议先把报错信息完整截图或复制然后执行一次jupyter --version把版本信息和日志整理在一起检索会比直接搜“Jupyter 报错”更有用。建议收藏本文下次遇到启动或执行问题时可以快速回到这里重新确认方向。