importnb可直接导入.ipynb文件,需用with importnb.notebook():包裹import语句,支持同目录notebook动态加载与调用,但会完整执行且不支持跨目录相对导入。

用 importnb 直接 import 一个 .ipynb 文件
Jupyter Notebook 本身不支持像 Python 模块那样直接 import xxx.ipynb,但 importnb 是最轻量、最贴近“原生 import 体验”的方案。它把 notebook 当作模块动态加载,执行其中的 top-level 代码,并暴露 __all__ 或所有全局变量。
安装和使用很简单:
pip install importnb
在 notebook 中:
import importnb
with importnb.Notebook():
import my_utils # 假设当前目录下有 my_utils.ipynb
- 必须用
with importnb.Notebook():上下文管理器包裹import语句 -
my_utils.ipynb里的函数、类、变量会像普通模块一样可用,比如my_utils.some_function() - 注意:被导入的 notebook 会被完整执行一次(含所有 cell),副作用(如 print、绘图、文件写入)都会触发
- 不支持跨目录相对导入(比如
../lib/common.ipynb),路径需为相对于当前 notebook 的有效路径
用 nbimporter 替代 importnb(兼容旧版 IPython)
如果你用的是较老的 Jupyter/IPython 版本(如 importnb 可能报错,这时可换 nbimporter:
pip install nbimporter
然后在 notebook 开头运行:
import nbimporter import my_notebook # 自动识别 .ipynb 并加载
- 无需上下文管理器,更接近直觉,但内部机制是注册自定义 importer,稳定性略低
- 对 notebook 中的魔法命令(如
%matplotlib inline)支持不好,可能报NameError: name '__IPYTHON__' is not defined - 如果被导入的 notebook 含单元格级异常,
import会失败并中断,不像importnb那样默认忽略非 top-level 错误
导出成 .py 再 import —— 最稳定但要手动同步
真正生产环境推荐的做法:把逻辑抽到 .py,而不是依赖 notebook 间引用。如果已有 utils.ipynb,可一键转成 Python 文件:
jupyter nbconvert --to python utils.ipynb
生成 utils.py 后,直接用标准方式导入:
import utils utils.helper_func()
- 避免了 notebook 运行时环境差异(如 kernel 版本、magic 命令、display 对象)带来的不确定性
- IDE 补全、类型检查、单元测试都正常工作;
utils.py可被其他项目复用 - 缺点是修改
utils.ipynb后必须重新运行nbconvert,否则import的还是旧代码 —— 容易忘记同步,调试时尤其容易踩坑
为什么不用 %run?它和 import 的本质区别是什么
%run 看起来最简单:
%run ./data_loader.ipynb
但它不是 import,而是「执行」:所有变量、函数会注入到当前 notebook 的 global namespace,没有命名空间隔离。
- 无法做别名(
import data_loader as dl不成立),也不能选择性导入(from data_loader import load_csv失效) - 多次
%run同一 notebook 会重复执行全部 cell,可能导致重复注册、重复绘图、甚至重复写文件 - 变量名冲突风险高:如果
data_loader.ipynb定义了df,你当前 notebook 也有df,后者会被覆盖且无提示 - 它适合临时调试或快速复用一段脚本,不适合构建可维护的模块依赖关系
真正需要复用逻辑时,别贪快用 %run;要么走 importnb + 显式上下文,要么老老实实转成 .py —— 后者看似多一步,但省掉的排查时间远超预期。











