装 Jupyter 这件事说难不难可真能把人卡住。我带过不少刚入门的朋友十个里有八个栽在同一个坑里pip 敲完了jupyter notebook 也敲了浏览器就是弹不出来或者好不容易打开了单元格前面那个[*]星号转了三分钟也不肯变成[1]。这篇就把 Jupyter 的安装和使用从头到尾捋一遍Windows 为主macOS 和 Linux 的差异单独标出来命令都是可以直接抄的。装完你会得到一个能跑代码、能写笔记、能画图、能交报告的环境适合数据分析、算法试验、教学演示这类需要边算边看的场景。如果你只想找个写工程代码的编辑器那这玩意儿可能不是最优解后面我会说清楚它到底适合谁。1. 先搞明白 Jupyter 是什么再动手装1.1 它本质上是一个跑在浏览器里的交互式计算环境很多人第一次听说 Jupyter会以为它是个 IDE跟 PyCharm、VS Code 是一类东西。不完全对。Jupyter 拆开看是三层最底下是一个 Python 进程叫内核Kernel真正执行代码的是它中间是一层服务端负责接收你敲的命令、把结果丢回去最上面是浏览器里的界面你看到的那一格格输入框就是它渲染出来的。这三层分开有个巨大的好处界面崩了不影响内核里跑着的变量。你把浏览器标签页关了再重新打开http://localhost:8888之前定义的df、model全都还在。这一点跟普通脚本跑完就清空的体验完全不一样。另一层理解是笔记本Notebook本身就是一份 JSON 文件。你写进去的代码、Markdown、输出结果包括图片的 base64全都存在同一个.ipynb里。所以它能做到代码和结论放在一起这也是它在数据分析圈子里取代 Word 和 PPT 的根本原因——改一行代码整张图重新生成报告里不会出现过期的数字。1.2 Notebook、Lab、Jupyter Server 到底谁是谁这块最容易被各种名词绕晕尤其搜jupyter notebook 网页版jupyter lab的时候出来一堆看着像又不是的页面。我把关系理一遍。名称是什么启动命令我的建议Jupyter Notebook老的经典界面单文档、标签页式jupyter notebook从旧教程入手的话先用它够用JupyterLab新一代界面多面板、可拖拽、带终端和文件树jupyter lab新装的话直接上这个Jupyter Server底下那层服务端两者共用不直接启动不用管装的时候自动带nbconvert命令行导出工具jupyter nbconvert要批量导出时必须用需要说清楚一点Jupyter 没有官方的公网登录入口。搜jupyter notebook 网页版登录入口的人多半是把它跟某些在线托管服务搞混了。你装完之后浏览器自动打开的那个http://localhost:8888/?tokenxxxx就是所谓的网页版它只跑在你自己这台机器上token 是一串本地访问凭证跟账号密码不是一回事。从 Jupyter Notebook 7 开始经典界面底层已经换成了 JupyterLab 的组件所以pip install notebook装出来的其实是个用 Lab 内核渲染的经典外观。功能上没必要纠结选一个用顺手就行。1.3 谁适合用谁不用凑这个热闹我的判断标准很粗暴如果你的工作里存在我先这么试一下看看结果长什么样的循环Jupyter 就适合你。适合的人做数据清洗和探索的、跑模型调参需要反复看中间结果的、做教学演示要一步步推公式的、需要把代码和图拼成一份报告交出去的。不太适合的人写有多个模块互相依赖的工程项目的、需要严格单元测试和 CI 流程的、要打包成命令行工具发布的。这些场景用.py文件加正经 IDE 效率高得多。我见过有人把整个后端项目塞进 notebook 里写三百个单元格改一处要全量重跑那真是自己为难自己。2. 安装路线怎么选三条路各有各的适用面2.1 三条路线横向对比装 Jupyter 有三种主流方式选错了后面会麻烦所以先看这张表。路线命令入口体积适合谁主要缺点Anaconda图形安装包3-5 GB完全不想碰命令行的人装完一堆用不上的库环境容易乱官方 Python pippip install jupyterlab几百 MB想搞清楚依赖关系的人需要自己建虚拟环境Miniconda / uvconda/uv pip几百 MB需要多版本 Python 共存的人多学一套包管理命令我自己长期用的是第二条官方 Python 加 venv 加 pip。原因很简单出了问题我能立刻定位到是哪个包的锅Anaconda 出问题的时候你得先去查它自带的包和你 pip 装的包打没打架排查成本翻倍。不过如果是给完全零基础的人装我有时候还是会推荐 Miniconda。它比 Anaconda 干净又保留了 conda 在科学计算类二进制包上的优势numpy、pytorch 这类包 conda 装起来确实省心。2.2 Python 本体怎么装那个勾选项很关键Windows 上第一步是装 Python。官网下载页面上会有好几个版本选稳定版就行不用追最新的预览版。安装程序第一屏底下有两个复选框其中Add Python to PATH一定要勾上。这个选项干的事是把 Python 的安装目录写进系统环境变量Path里。勾了它你在任意目录下敲python都能找到解释器不勾你就得记住C:\Users\你的用户名\AppData\Local\Programs\Python\Python3xx\python.exe这么长一串路径每次手动敲。我看到有人因为没勾这个后面所有命令全报不是内部或外部命令一路怀疑人生。装完验证一下打开 PowerShell 或 CMDpython --version pip --version两行都能打印出版本号才算成。如果python报错但py能用说明系统里装了 Microsoft Store 版本的别名干扰去设置 - 应用 - 高级应用设置 - 应用执行别名里把 python 的两个别名关掉。macOS 上更推荐用 Homebrewbrew install python。Linux 上大部分发行版自带 python3检查一下python3 --version缺的话用apt install python3 python3-pip python3-venv补上。2.3 虚拟环境为什么必须建不建会怎样这一步新手最容易跳过也是后面出问题最多的根源。假设你系统的 Python 里直接pip install jupyterlab那么所有包都装在全局 site-packages 里。过两个月你装另一个项目它要求 pandas 2.0而你之前那套代码是按 pandas 1.5 写的一升级老代码全崩。这种版本地狱在数据圈是常见事故。虚拟环境就是给每个项目划一块独立的地盘。原理是把 Python 解释器和一个独立的site-packages目录绑定在一起激活环境后 pip 装的东西只进这块地盘跟全局互不干扰。# 在你想放项目的目录下执行 mkdir D:\work\jupyter-demo cd D:\work\jupyter-demo python -m venv .venvWindows 激活.venv\Scripts\activatemacOS / Linux 激活source .venv/bin/activate激活成功的标志是命令行提示符前面多了一个(.venv)。这时候再敲where pythonWindows或which python应该指向你项目目录里的那个解释器而不是系统目录。这一步一定要验证装了半天发现装到全局去了是高频事故。注意PowerShell 下激活可能报禁止运行脚本。这不是环境坏了是执行策略默认拦着。用管理员身份打开 PowerShell 执行Set-ExecutionPolicy -Scope CurrentUser RemoteSigned或者干脆切回 CMD 执行activate.bat都能绕过。3. 从零到跑起来的完整实操3.1 装 JupyterLab 和 Notebook虚拟环境激活后装包就是一行pip install jupyterlab notebook想快一点的话换国内镜像源加个参数就行。装完可以用pip list确认看到jupyterlab、notebook、jupyter-server、ipykernel这几个都在说明基础齐了。这里有个细节值得说ipykernel是必须的。它是 Python 与 Jupyter 之间通信的桥梁负责把你的代码翻译成内核能理解的格式。有些精简安装方式会漏掉它导致你新建笔记本的时候发现没有可用的内核页面一片空白。如果你用的是 uv流程是这样的uv venv uv pip install jupyterlab notebook速度上比 pip 快一个量级尤其在装大型科学计算包的时候差别特别明显。3.2 把虚拟环境注册成内核这一步不做后面会疼光装好了还不够。Jupyter 启动的时候会去扫描系统里有哪些内核规格kernelspec如果你的虚拟环境没注册它要么找不到要么只能用系统全局的那个 Python于是你辛苦建的隔离环境白费。注册命令python -m ipykernel install --user --namejupyter-demo --display-name Python (jupyter-demo)解释一下这几个参数--user表示只给当前用户装不需要管理员权限--name是内部标识符用英文小写和连字符别用中文和空格--display-name是你在界面上看到的那个名字这个可以随便写中文也行。注册完之后可以用这条命令查看已注册的内核jupyter kernelspec list输出里能看到内核名字和它对应的目录。如果哪天内核乱了用jupyter kernelspec remove 内核名删掉重新注册。心得--name我习惯和项目目录名保持一致比如项目叫sales-analysis内核就叫sales-analysis。半年后回来一看就知道该切哪个不用去翻 pip list。3.3 首次启动与工作目录的正确设置启动命令jupyter lab敲下去之后正常情况下浏览器会自动弹出来地址栏是http://localhost:8888/lab?token一长串字符。但默认的工作目录是你执行命令时所在的目录如果你在C:\Windows\System32里敲的那文件树展开就是系统目录找项目文件得点半天。稳妥做法是每次都先cd到项目目录再启动或者直接改配置文件。改配置文件分两步。先生成jupyter lab --generate-config它会告诉你配置文件落在哪Windows 一般是C:\Users\你的用户名\.jupyter\jupyter_lab_config.pymacOS 和 Linux 是~/.jupyter/jupyter_lab_config.py。用文本编辑器打开找到这几行改掉文件里都是注释状态把前面的#去掉c.ServerApp.root_dir D:/work/jupyter-demo c.ServerApp.port 8888 c.ServerApp.open_browser True c.ServerApp.allow_remote_access False路径这里有个坑Windows 路径的反斜杠在 Python 字符串里是转义符D:\work里的\w会被当成转义序列。老老实实用正斜杠D:/work/jupyter-demo省事又不出错。allow_remote_access保持False是我的个人习惯本地用不到远程访问关掉少一份风险。如果你用的是老版本 Notebook 6配置文件的类名是NotebookApp而不是ServerApp参数写法一样把前缀换掉就行。Jupyter Notebook 7 和 Lab 都统一用ServerApp了。3.4 macOS 和 Linux 上的三处差异大部分流程一样但有三点要注意。第一是激活命令不同前面已经说过用source .venv/bin/activate。第二是配置文件路径在~/.jupyter/下~就是家目录不用写全路径。第三是Linux 服务器上通常没有图形界面jupyter lab会提示找不到浏览器得加--no-browser参数然后自己把终端里打印出来的那个带 token 的链接复制到本地浏览器打开。另外 macOS 从某个版本开始python命令默认不存在只有python3虚拟环境里才会有python。这不是装错了是系统的设计虚拟环境激活后就正常了。4. 单元格Jupyter 全部操作的核心4.1 三种单元格模式各管一件事笔记本里每一个格子叫单元格Cell分三种类型切换方式是按Esc进命令模式后按M转 Markdown或Y转代码。Code 单元格执行代码左边有In [ ]的标记。Markdown 单元格渲染成排版好的文字用来写说明、公式、标题。Raw 单元格原样输出导出的时候才会体现日常基本用不上。Markdown 单元格里写 LaTeX 公式要用美元符号包裹行内公式用单个$Emc^2$独立成行的公式用双美元符号行内公式$a^2 b^2 c^2$ 独立公式 $$ \frac{\partial f}{\partial x} 2x $$公式渲染依赖 MathJax首次加载会稍微慢一点属正常现象。4.2 执行顺序和内核状态为什么代码没有任何反应这是搜索量最高的问题之一——jupyter notebook 单元格执行代码没有任何反应。原因通常有六种按出现频率排第一种内核正在忙。单元格左边显示[*]说明代码在跑。这时候点别的单元格执行会排队等待。如果它一直不结束八成是死循环或者卡在网络请求上了。别犹豫菜单栏 Kernel - Interrupt 中断不行就 Restart。第二种代码在等输入。你在单元格里写了input()但这个交互输入框在网页界面里显示得很不明显有时候压根没弹出来看着就像卡住了。Notebook 里尽量不要用input()参数写死在代码里或者用 widget 替代。第三种内核已经死了。可能是内存爆了跑大数据集时常见也可能是底层库崩了。表现是执行一直不返回右上角内核状态灯变成实心圆或者干脆变灰。菜单栏 Kernel - Restart Kernel 重启。第四种输出被折叠了。长输出右侧有个滚动条你以为没结果其实结果在下面滚一下就行。第五种在 Markdown 模式下按了运行。这时候按ShiftEnter只是渲染 Markdown当然不会出结果。按Esc再按Y切回代码模式。第六种pip 装包卡住了。在单元格里写!pip install xxx网络不好时会静默等很久。实测经验判断内核是不是真死了最快的办法是新建一个空白单元格敲print(1)执行。能立刻打印出 1说明内核活着转圈不返回直接 Restart别浪费时间排查。4.3 我实际天天在用的快捷键快捷键分两套按Esc进命令模式左边竖条变蓝按Enter进编辑模式。下面这张表是我用下来最值钱的几个。快捷键模式作用Shift Enter通用执行当前单元格并跳到下一个Ctrl Enter通用执行当前单元格光标不动Alt Enter通用执行并在下方插入新单元格A/B命令在上方 / 下方插入单元格D D命令删除当前单元格连按两次 DM/Y命令转 Markdown / 转 CodeZ命令撤销删除单元格Shift M命令合并选中的多个单元格Ctrl /编辑注释或取消注释选中行Shift Tab编辑查看函数的参数提示Ctrl Shift -编辑在光标处拆分单元格F命令查找替换Shift Tab这个我特别想强调在函数括号里按一下出简要提示连按两下出完整文档连按三下直接弹出帮助面板。少查多少次文档全靠它。4.4 代码自动补齐怎么开搜jupyter notebook 代码自动补齐的人很多因为默认的补全确实不够聪明要按Tab才触发而且只补当前内核里已知的名字。JupyterLab 4 自带一个连续提示功能在 Settings - Settings Editor - Code Completer 里把continuousHinting勾上打字的时候就会自动弹候选。勾之前建议先把kernelResponseTimeout调大一点不然大文件里会有点卡。想要真正接近 IDE 的体验装 LSP 插件pip install jupyterlab-lsp jupyter-lsp-python装完重启 JupyterLab它会自动拉起 Python 语言服务器提供跨文件跳转、变量重命名、实时错误提示。这个组合我用了两年多稳定性和补全质量都在线。在老版 Notebook 6 里得靠 nbextensions 的 Hinterland 扩展pip install jupyter_contrib_nbextensions jupyter contrib nbextension install --user jupyter nbextension enable hinterland/hinterland不过 Notebook 6 现在属于维护状态了新项目我建议直接上 Lab。5. 用 Markdown 把笔记本变成一份能交出去的文档5.1 常用语法速查Jupyter 里的 Markdown 和标准 Markdown 基本一致多了一些细节。语法效果备注# 标题一级标题会被目录面板抓取**加粗**加粗 引用引用块用来写注意事项- 项目无序列表| 表头 |表格Jupyter 里表格必须前后留空行python 代码块标注语言才有高亮[文字](#锚点)内部跳转锚点就是标题原文$公式$行内公式br强制换行Markdown 里单个回车不换行表格前后必须空一行这条特别容易忘。写成了紧贴上一段文字渲染出来会是一坨竖线排查半天。5.2 生成可点击目录的两种做法jupyter notebook 怎么生成 markdown 目录语法这个问题答案取决于你要的是界面里的导航还是文档里的目录。先说界面导航。JupyterLab 左侧边栏自带 Table of Contents 面板点那个像列表的图标就出来了它会自动扫描所有 Markdown 标题点一下直接跳。这是最省事的方式什么都不用装。再说文档里的目录也就是导出成 HTML 之后还能点的那种。做法是手写链接格式是[显示文字](#标题原文)## 目录 - [一、数据加载](#一数据加载) - [二、清洗流程](#二清洗流程) - [三、结论](#三结论) ## 一、数据加载 ## 二、清洗流程 ## 三、结论锚点规则是把标题里的空格去掉、特殊符号去掉、标点去掉中文和数字直接保留。上面## 一、数据加载的锚点就是#一数据加载顿号被丢掉了。这个规则坑了不少人写错了点了没反应。如果你在 Notebook 6 时代可以用 nbextensions 里的 Table of Contents (2) 扩展它支持自动生成带编号的目录并插入单元格比手写省事。5.3 导出 HTML、Markdown 和 PDF导出在 File - Save and Export Notebook As 里对应命令行工具是 nbconvert。目标格式命令坑点HTMLjupyter nbconvert --to html 文件.ipynb最稳图片内嵌直接发人Markdownjupyter nbconvert --to markdown 文件.ipynb图片会单独存一个文件夹PDFWebPDFjupyter nbconvert --to webpdf 文件.ipynb要先装 playwright 和 chromiumPDFLaTeXjupyter nbconvert --to pdf 文件.ipynb中文要配 xelatex最折腾Python 脚本jupyter nbconvert --to script 文件.ipynb调试和提交代码时好用导出 PDF 是坑最多的环节。LaTeX 路线需要本地装完整的 TeX 发行版还要额外配置中文字体动辄几个 GB。我现在的做法是用 WebPDFpip install nbconvert[webpdf] playwright install chromium jupyter nbconvert --to webpdf --allow-chromium-download 文件.ipynb它本质是把页面渲染出来后打印成 PDF中文字体直接跟着系统走不用额外折腾。把.ipynb转成.py这个操作也值得记一下。转出来的文件里Markdown 单元格会变成注释代码单元格原样输出。要交付纯代码或者拿去做静态检查的时候特别方便。6. 打不开、没反应、连不上故障速查6.1 浏览器弹不出来网页也打不开症状是命令敲下去终端打印了一堆日志但浏览器毫无动静。第一步先别慌看终端最后几行肯定有一行http://127.0.0.1:8888/lab?tokenxxxx。手动把这行完整复制到浏览器地址栏一般就能进。如果手动复制也打不开检查这几个方向一是配置文件里open_browser被设成了False。有些教程教你关掉自动弹窗结果自己忘了还以为是坏了。二是默认浏览器被系统设成了某个不响应命令行调用的程序。这种情况直接在地址栏输http://localhost:8888再粘贴 token。三是端口被占用。终端日志里会明确写Address already in use。解决办法是换端口启动jupyter lab --port 8890四是 token 变了。每次启动服务token 都会重新生成。你如果存了旧链接的收藏夹自然登不上。查当前 token 用jupyter server list它会列出正在运行的服务、端口和 token。6.2 单元格执行没有任何反应排查顺序这个问题的排查有个固定顺序照着走基本都能定位。先看单元格左边的标记。是[ ]说明还没执行可能是快捷键被输入法截了切英文输入法再试。是[*]说明正在跑等或者中断。是[数字]说明执行完了那问题出在没有输出而不是没有执行检查代码里有没有写 print 或者最后一行表达式的值。再检查是不是在等输入。搜一下代码里有没有input()、getpass()这类阻塞调用。然后是内存。跑大文件的时候内存占满会让进程被系统杀掉界面上表现为内核悄悄断开。这种情况在 Lab 里右上角的内核状态会变菜单栏 Kernel - Restart Kernel 重启后先用!free -hLinux或任务管理器看内存占用把数据集分块处理。最后考虑版本冲突。某些库的旧版本在 Jupyter 环境下会有兼容问题pip list看一下有没有装了多个版本的科学计算包。我的习惯是新建环境的时候先pip install numpy pandas matplotlib ipykernel把地基打稳再装业务库。6.3 内核连不上、模块导不进来明明 pip 装了import 还是报 ModuleNotFoundError——这是虚拟环境没配对最典型的表现。原因几乎总是你装包的 pip 和你内核用的 python 不是同一个。验证方法是在单元格里执行import sys print(sys.executable)再把终端里的which python或where python输出对比一下。两个路径不一致就是内核挂错了。回到终端激活正确的虚拟环境重新执行一遍python -m ipykernel install就解决了。另一种情况是用!pip install在单元格里装包。这个写法在虚拟环境里一般没问题但如果环境本身就乱了它可能装到别处去。我更推荐在终端里用带-m的写法python -m pip install 包名python -m pip能保证用的是当前这个 python 对应的 pip比裸敲pip稳。6.4 设置访问密码别再被 token 烦token 每次变确实烦。设个固定密码jupyter server password它会提示你输入密码然后把哈希值写进~/.jupyter/jupyter_server_config.json。之后启动服务浏览器只要输这个密码就行token 参数可以忽略。想换密码再执行一遍同样的命令覆盖即可。这个密码是明文存储在本地配置文件里的哈希形式千万别用你其他账号在用的密码。如果你压根不想设密码比如本机自用也可以在配置文件里加c.ServerApp.token c.ServerApp.password 但我不推荐这么干。哪怕只在本机跑浏览器插件、局域网里其他设备都可能摸到这个端口有个门槛总是好的。7. 把 Jupyter 接进日常工作流7.1 在内网服务器上跑本地浏览器访问这台机器性能不够但隔壁有台配置好的服务器公司内网的、或者你自己机房里那台这是很常见的场景。思路是让 Jupyter 在服务器上跑但不弹浏览器本地通过端口转发连过去。服务器上执行jupyter lab --no-browser --port 8890 --ip0.0.0.0--ip0.0.0.0表示监听所有网卡。这一步要注意如果服务器暴露在不受控的网络里一定要配合密码和防火墙规则别裸奔。然后在你本地机器的终端里做端口转发ssh -L 8888:localhost:8890 用户名服务器地址这条命令的意思是把本地 8888 端口的流量通过这条连接转发到服务器上的 8890 端口。执行后保持这个终端窗口开着本地浏览器访问http://localhost:8888就能看到服务器上的 Jupyter 了。这种方式的优点是全程加密而且不需要在服务器上开放额外端口。缺点是这个终端窗口不能关我一般会挂在一个专门的标签页里。注意--ip0.0.0.0加c.ServerApp.allow_remote_access True的组合等于把服务暴露给整个网段。如果必须这么配至少要把密码设上并且确认服务器所在网络是可信的。我在客户现场见过没设密码就开着的实例那真是谁都能进。7.2 插件和中文界面JupyterLab 的插件生态是它比经典 Notebook 强的地方。几个我装了就没卸过的jupyterlab-language-pack-zh-CN中文语言包。装完在 Settings - Language 里选中文界面就全中文了。这一点对完全零基础的人特别友好标题里说懂中文就会不是开玩笑。jupyterlab-lsp前面提过的语言服务器提供补全、跳转、诊断。jupyterlab-git在界面里直接做 Git 提交和分支切换。适合不想来回切终端的人。jupyterlab-variableInspector侧边栏实时显示当前内核里所有变量的名字、类型、值。调数据的时候特别有用不用每次都敲df.head()。装插件的通用方式是先用pip搜一下有没有对应的 Python 包pip install完之后重启 JupyterLab。Lab 4 之后大部分插件走的是预构建机制不需要再跑jupyter labextension install那套老流程了。至于 Neovim 用户搜的jupyter notebook nvim思路是用 jupytext 把.ipynb和.py双向同步笔记本里写编辑器里改两边实时对应。或者用支持 notebook 的 Neovim 插件直接在编辑器里连内核。这条路线配置成本不低适合已经很熟 Neovim 的人。7.3 和 VS Code、PyCharm 怎么分工这三者不是竞争关系我现在是混着用。JupyterLab 用来做探索性的工作加载数据看看长什么样、试几个特征工程的想法、画图看分布。它的优势是状态保留一个变量不用反复重算。VS Code 用来做整理和交付把笔记本里验证过的逻辑抽成函数写成.py写测试提交 Git。VS Code 也支持直接打开.ipynb并连内核运行界面更接近传统编辑器改代码效率高。PyCharm 专业版对 Jupyter 的支持也不错尤其在大型项目里跨文件跳转和重构更顺手。社区版的支持相对弱一些如果只是跑 notebook用不用都行。我的实际操作流程是在 JupyterLab 里想清楚在 VS Code 里写成模块再回到 JupyterLab 里调用和展示。这样既保留了探索的灵活性又不会让代码烂在 notebook 里。7.4 大数据集和长任务的处理习惯notebook 有个天然缺陷所有变量都常驻内存。你随手定义五个 DataFrame每个 2GB内存就爆了。我的做法是把大计算的结果缓存成文件用的时候读缓存。Parquet 格式读写快、体积小是首选df.to_parquet(cache/cleaned_data.parquet) df pd.read_parquet(cache/cleaned_data.parquet)中间用不到的变量及时删del big_df import gc gc.collect()耗时超过十分钟的任务别在 notebook 里干等写成.py脚本用后台跑跑完把结果落盘notebook 里只读结果。这样还避免了内核一崩全白干的悲剧。8. 用久了才明白的几个习惯8.1 顺序执行的假象是 notebook 最大的陷阱notebook 允许你乱序执行单元格这既是它灵活的地方也是它最容易骗人的地方。举个我亲身踩过的例子我先执行了单元格 5 定义了threshold 0.8又回头改了单元格 3 的代码然后直接跳去执行单元格 8。这时候单元格 8 用的是旧的threshold结果看着正常但其实逻辑已经跟代码不一致了。等你把整个笔记本分享出去别人从头往下执行结果完全对不上。规避方法只有一个定期做 Restart Kernel and Run All。菜单栏 Kernel 里就有快捷键是Ctrl Shift F5之类视版本而定直接点菜单最稳。让整个笔记本从头到尾跑一遍中间报错就说明有隐藏的状态依赖。我现在养成了习惯写完一段逻辑先 Restart Run All 一遍只保留真正需要的输出把调试过程中产生的临时打印全删掉再保存。8.2 文件命名和目录结构的小约定.ipynb文件名我坚持只用小写英文加连字符不用空格和中文。原因很实际中文和空格在命令行、URL、Git 里都可能出问题尤其导出和转发的时候。目录上我一般这么分project/ data/ 原始数据只读不改 cache/ 中间结果可以随时删 notebooks/ 笔记本按 01_ 02_ 编号 src/ 抽出来的模块 output/ 图表和报告data/设成只读这个习惯救过我一次。有回清洗脚本写错了直接把原始数据覆盖了好在有备份。从那以后所有对原始数据的处理都先 copy 一份出来。8.3 把 notebook 提交到 Git 的几个坑.ipynb是 JSON里面包含输出结果和执行的计数。这导致两个问题一是 diff 没法看全是 base64 的图片二是每次运行计数变了文件就变成已修改提交记录一片噪音。解决办法是nbstripout它会在提交前自动清掉输出pip install nbstripout nbstripout --install这个命令会在仓库的.git/config里配一个 filter之后git add的时候自动剥离输出。团队协作的时候特别值得加上能省掉无数次这篇改了啥的困惑。另一个工具是jupytext它让.ipynb和.py文件保持同步。好处是你在git diff里看到的是纯 Python 代码的差异一目了然。代价是多一个配置文件要维护。如果团队里有人不用 Jupyter我一般会在仓库里同时放.ipynb和用 nbconvert 导出的.pyPR 里审代码看.py跑的时候用.ipynb。8.4 内核重启是常态别把它当故障最后说一个心态问题。刚从 PyCharm 转过来的人看到内核重启会觉得是出 bug 了。其实不是。Jupyter 的模型是长时间驻留的进程跑久了内存碎片化、临时对象堆积、某些库的状态被污染都是正常现象。我感觉笔记本用了两三个小时、或者跑了十几次大计算之后结果开始变得奇怪直接重启内核重新跑一遍往往问题就没了。我现在的习惯是每完成一个分析阶段就重启一次。反正数据是落盘的重启成本就是几十秒。这比在一个状态混乱的环境里debug半小时要划算得多。另外提醒一句用笔记本处理敏感数据的时候要留意两点一是输出结果会永久存在.ipynb文件里包括你打印出来的原始数据二是有时候一个df.head()就能把客户信息写进文件。分享之前记得清理输出这跟前面说的 nbstripout 顺手就一起解决了。真正用顺手之后你会发现Jupyter 的价值不在于它能跑代码——能跑代码的工具太多了——而在于它把试错这件事的成本压到了最低。改一个参数按一下Shift Enter图就变了不用切窗口、不用重新加载数据、不用等启动。这种反馈速度上的差异日积月累会实实在在改变你探索问题的深度。