命令行工具
AnswerDotAI/nbdev avatar
AnswerDotAI/nbdev

nbdev 3 实测指南:从 Jupyter Notebook 到 PyPI 发布,配置迁移与工作流解析

使用 Jupyter Notebooks 创建令人愉悦的软件。文档支持 LaTeX、可搜索、自动超链接(包括通过 nbdev-index 对许多包的开箱即用支持)将包发布到 PyPI 和 conda 以及简化包发布的工具。

5,316 个 Star513 个 ForkJupyter NotebookApache-2.0

秒懂

它是什么?
nbdev 3 将配置从 settings.ini 迁移到 pyproject.toml,并继续以 Notebook 为唯一代码源生成文档、测试和包。本文解析其机制、命令和迁移路径,并指出适合与不适合的人群。
适合谁用?
nbdev 3 适合那些已经把 Jupyter Notebook 当作主要编码环境,并且愿意接受 Notebook 作为唯一事实来源的开发者,尤其是 fast.ai 生态的追随者。它不适合需要复杂构建流程、非 GitHub 托管或 Windows 原生环境的团队。
能商用吗?
可以。Apache-2.0 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
还在维护吗?
在维护。仓库最近一次提交在 2 天前。
用什么语言写的?
主要是 Jupyter Notebook(依据 GitHub 的语言统计)。

以上回答依据项目的 GitHub 数据(最近同步于 2026年9月14日)和我们的分析,不构成法律意见。

开源项目深度解析

Notebook 作为唯一代码源:nbdev 的核心理念

nbdev 解决的问题很具体:让开发者用 Jupyter Notebook 写代码,同时自动获得传统 IDE 工作流中的文档、测试和打包能力。它的设计前提是 Notebook 单元格就是代码单元,每个被导出的单元格对应一个 Python 模块中的函数或类。这种模式与常见的「Notebook 只做探索,正式代码另写 .py 文件」的做法截然不同。nbdev 要求你信任 Notebook 的版本控制能力,并通过 Jupyter/git hooks 清理元数据、以可读格式渲染合并冲突。如果你不打算把 Notebook 当作唯一事实来源,nbdev 的价值会大打折扣。

从 settings.ini 到 pyproject.toml:nbdev 3 的迁移机制

nbdev 3 在 2026 年 1 月引入了一个重大变更:配置从 settings.ini 迁移到 pyproject.toml,遵循 PEP 621。项目元数据放在标准的 [project] 段,而 nbdev 专属设置放在 [tool.nbdev] 段。迁移命令是 nbdev-migrate-config,它会在项目根目录自动转换配置,并更新 GitHub Actions 工作流到 nbdev3 兼容版本。README 明确说现有 Notebook 和代码不需要任何改动。这听起来很省事,但要注意:迁移脚本会改写你的工作流文件,如果你自定义过 CI,需要先备份。此外,nbdev2 的 settings.ini 中的一些非标准键可能无法完美映射到 PEP 621,迁移后应仔细检查 [tool.nbdev] 的内容。

核心命令链:从 Notebook 到 PyPI 的完整流程

nbdev 提供了一组命令,覆盖从创建项目到发布的每个环节。新建项目用 nbdev-new,它会生成一个包含 pyproject.toml 的骨架。日常开发中,nbdev-export 将 Notebook 导出为 Python 模块,nbdev-test 并行运行测试,nbdev-docs 生成 Quarto 文档和 README。发布时,nbdev-release-gh 调用 nbdev-changelog 从 GitHub issues 生成变更日志,然后打 tag 并创建 release。nbdev-pypi 负责构建并上传到 PyPI,nbdev-conda 生成 meta.yaml 并可选构建 conda 包,nbdev-release-both 一次发布到两个平台。整个流程以 GitHub Actions 为 CI 基础,所以如果你的仓库不在 GitHub,这些命令的自动化部分会失效。

文档生成与自动链接:Quarto 和 nbdev-index 的配合

文档系统是 nbdev 的一个亮点。nbdev-docs 使用 Quarto 渲染 Notebook,生成支持 LaTeX、可搜索的文档网站,并自动为函数签名添加超链接。nbdev-index 提供了对许多第三方包的开箱即用链接支持,这意味着文档中的 API 引用会自动指向对应包的文档。这种自动链接省去了手写交叉引用的麻烦。但代价是文档的样式和结构被 Quarto 的工作流绑定,如果你需要高度定制的文档站点,可能得放弃 nbdev 的默认渲染。另外,nbdev-docs 会覆盖 README.md,所以手动编辑 README 的改动会被覆盖,除非你修改 index.ipynb。

同步机制:双向同步与 cell ID 的可靠性

nbdev 提供 Notebook 与纯文本源码之间的双向同步。nbdev-update 将模块中的变更传播回创建它们的 Notebook,nbdev-export 将 Notebook 导出为模块。同步的可靠性依赖于每个导出单元格都带有唯一的 Notebook cell ID,这样更新时总能定位到正确的单元格。这种设计比基于行号的同步更健壮。但反过来,它也意味着你不能随意在 .py 文件中手动编辑代码,因为那会破坏与 Notebook 的对应关系。README 建议用 IDE 进行代码导航或快速编辑,但任何实质性修改都应在 Notebook 中进行,然后重新导出。如果你习惯于在 .py 文件中做大量重构,这个约束会很不舒服。

测试与 CI:并行测试和 GitHub Actions 的绑定

测试被当作一等公民。你可以把测试写成 Notebook 单元格,nbdev-test 会并行运行所有匹配的 Notebook。CI 由 GitHub Actions 提供,自动运行测试并重建文档。这种集成让测试成为开发流程的自然部分,而不是事后补充。但注意,nbdev 的 CI 模板是预设的,如果你需要多平台测试、矩阵构建或自定义缓存策略,可能需要改写模板。另外,nbdev 明确不支持 Windows 原生环境,只支持 WSL。对于 Windows 用户,这意味着所有 nbdev 命令都必须在 WSL 中运行,这增加了环境复杂度。如果你所在团队以 Windows 为主,nbdev 可能不是最佳选择。

限制与失败模式:混合单元格警告和迁移风险

nbdev 有一个强制规则:未导出的单元格不能混用 import 语句和其他代码。例如,一个单元格里既写 import some_module 又调用 some_module.something() 会触发警告。原因是文档生成时需要确保函数签名是最新的,混合单元格会导致签名解析失败。这个规则要求开发者养成拆分的习惯,但也会打断自然的探索流程。迁移到 nbdev3 时,nbdev-migrate-config 会改写 GitHub Actions 工作流,如果你有自定义步骤,可能会被覆盖。此外,nbdev 的发布流程依赖 GitHub issues 生成 changelog,如果你的项目不使用 GitHub issues,nbdev-changelog 将无法工作。

替代方案与选择建议

与 nbdev 最接近的替代方案是 Jupytext,它将 Notebook 与 .py 或 .md 文件配对,允许在 IDE 中编辑纯文本,同时保留 Notebook 格式。区别在于 Jupytext 不强制 Notebook 为唯一代码源,它更灵活,但也不提供 nbdev 的文档生成、测试集成和打包流水线。另一个方向是放弃 Notebook,直接用 Poetry 或 Hatch 管理项目,配合 Sphinx 或 MkDocs 生成文档。这种传统方式更可控,但失去了 Notebook 的交互式调试优势。选择取决于你是否接受 nbdev 的约束:所有代码从 Notebook 导出,文档由 Quarto 渲染,CI 绑定 GitHub Actions。如果这些约束与你的工作流冲突,传统工具链会更合适。

编辑结论

nbdev 3 适合那些已经把 Jupyter Notebook 当作主要编码环境,并且愿意接受 Notebook 作为唯一事实来源的开发者,尤其是 fast.ai 生态的追随者。它不适合需要复杂构建流程、非 GitHub 托管或 Windows 原生环境的团队。在采用前,先确认你的项目能否满足两个硬性条件:所有代码必须能拆分为可导出的 Notebook 单元格,且每个单元格只能包含单一类型的语句。运行 nbdev-migrate-config 前备份 settings.ini,并检查生成的 pyproject.toml 中 [tool.nbdev] 段的每个键是否符合预期。最后,验证 nbdev 3 的 GitHub Actions 模板是否与你现有的 CI 流程兼容,因为迁移脚本会覆盖工作流文件。

官方来源

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
社区笔记

社区笔记