%run是最直接的脚本执行方式,支持相对/绝对路径及命令行参数,脚本在当前内核中运行并污染命名空间;%load用于调试,将代码注入单元格后手动执行;终端执行则完全隔离。

%run 是最直接、最常用的方式,无需转换格式、不改代码、不启新进程,脚本在当前内核上下文中执行。
%run 能运行哪些路径下的 .py 文件
它支持相对路径、绝对路径和带参数的调用,但路径解析基于 notebook 当前工作目录(不是 notebook 文件所在目录)。
- 用
%pwd确认当前工作目录,不是%cd切换后的路径或 notebook 保存位置 - 同目录脚本:直接写
%run script.py - 子目录脚本:写
%run ./src/main.py或%run src/main.py(点斜杠可省略) - 绝对路径:如
%run /home/user/project/utils.py,注意路径中空格需加引号 - 传参:支持
%run script.py arg1 arg2,参数会进sys.argv,但不会自动进argparse—— 脚本得自己处理
%run 和模块导入 import 的关键区别
两者都能“执行”脚本,但语义和行为完全不同:前者是运行,后者是加载定义。
-
%run script.py会逐行执行,print输出立即显示,全局变量(如a = 10)会留在当前命名空间里,后续单元格能直接用a -
import script只加载模块定义,不执行if __name__ == '__main__':下的代码,除非显式调用script.main() - 如果脚本没加
if __name__ == '__main__':保护,import也会触发主逻辑 —— 这常导致意外重复执行 -
%run不受sys.path影响;import必须确保脚本所在目录在sys.path中,否则要先sys.path.append(...)
为什么 %load 更适合调试而不是运行
%load 不是执行命令,而是代码搬运工 —— 它把外部文件内容原样塞进当前单元格,之后你才能编辑、分步运行、打断点。
- 执行
%load utils.py后,整个文件变成单元格内容,按Shift+Enter才真正运行 - 适合快速验证某段逻辑、临时改参数、插
print或breakpoint() - ⚠️ 坑:再次执行
%load utils.py会覆盖你刚改的代码,丢失修改 - 不推荐用于自动化流程或批量执行 —— 每次都要手动点运行,没法写成连续步骤
终端执行 python xxx.py 和 %run 的实际差异
看起来都是“跑脚本”,但环境隔离程度差很多:
- 终端里跑
python xxx.py是全新 Python 进程,完全独立于 notebook 内核,变量、导入状态、已安装包版本都不共享 - 输出只在终端窗口,不能和 notebook 单元格联动,也没法用
%%time魔法测耗时 - 若脚本依赖 notebook 中已初始化的对象(比如一个训练好的
model),终端方式根本访问不到 - 适合场景仅限:导出数据、生成文件、长时间后台任务(避免 notebook 卡死)
真正容易被忽略的是工作目录和命名空间污染:%run 看似简单,但它让脚本和 notebook 共享全部变量名 —— 如果脚本里也定义了 df,就会悄悄覆盖你前面辛苦清洗好的 DataFrame。


















