Jupyter Notebook 不仅适合交互式编写和调试 Python 代码,也可以直接调用已经保存好的 .py 文件。根据文件内容、执行目的以及开发习惯不同,可以选择不同的运行方式。常见方法主要有四种:使用 %run 魔法命令、使用 exec() 执行文件内容、通过 subprocess 调用 Python 解释器,以及在终端中使用 python 命令运行脚本。
一、使用 %run 命令运行 Python 文件
%run 是 Jupyter Notebook 中最直接、最常用的运行 Python 文件方法,特别适合需要在 Notebook 环境中测试现有 Python 脚本的场景。
假设当前目录下存在一个 test.py 文件:
Python运行print("Hello Jupyter") name = "Python" print(name)
在 Jupyter Notebook 单元格中直接执行:
Python运行%run test.py
运行结果:
Hello Jupyter Python
如果 Python 文件不在当前工作目录,可以指定完整路径或相对路径:
Python运行%run ./scripts/test.py
Windows 环境也可以使用:
Python运行%run D:/python_project/test.py
使用 %run 的一个重要特点是,脚本执行完成后,其中定义的变量、函数和类通常可以直接在当前 Notebook 环境中继续使用。例如:
Python运行# test.py message = "Hello Python" def add(a, b): return a + b
Notebook 中执行:
Python运行%run test.py
随后可以直接调用:
Python运行print(message) print(add(10, 20))
输出:
Hello Python 30
因此,如果目标是“运行一个 .py 文件,并继续使用其中定义的变量和函数”,%run 通常是优先选择。
%run 传递命令行参数
如果 Python 文件需要参数,也可以直接写在文件名后面:
Python运行%run test.py hello 123
脚本中可以通过 sys.argv 获取参数:
Python运行import sys print(sys.argv)
这种方式比较适合测试带有命令行参数的 Python 程序。
%run 指定运行目录
某些脚本依赖特定工作目录,可以使用 -i、-n 等参数控制执行行为。例如:
Python运行%run -i test.py
-i 表示在当前交互式命名空间中执行脚本,可以方便脚本访问 Notebook 中已经定义的变量。
二、使用 exec() 执行 Python 文件
第二种方式是使用 Python 内置的 exec() 函数读取 .py 文件内容,然后动态执行。
最简单的写法如下:
Python运行exec(open("test.py", encoding="utf-8").read())
如果文件路径不同,可以修改为:
Python运行exec(open("./scripts/test.py", encoding="utf-8").read())
这种方法本质上是先读取 Python 文件中的源代码,再将代码交给 Python 解释器执行。
例如 test.py 内容为:
Python运行x = 100 y = 200 print(x + y)
Notebook 中执行:
Python运行exec(open("test.py", encoding="utf-8").read())
输出:
300
同时,x 和 y 也会出现在当前执行环境中:
Python运行print(x) print(y)
结果:
100 200
使用 exec() 时需要注意编码
如果 Python 文件包含中文内容,建议显式指定编码:
Python运行exec(open("test.py", encoding="utf-8").read())
这样可以降低因为系统默认编码不同而产生的 UnicodeDecodeError 风险。
exec() 更适合什么场景
exec() 灵活性较高,可以动态加载和执行字符串形式的 Python 代码。例如:
Python运行code = """ a = 10 b = 20 print(a + b) """ exec(code)
不过,如果只是为了在 Jupyter Notebook 中运行一个普通 .py 文件,通常没有必要优先使用 exec()。相比之下,%run 可读性更好,而且专门针对 Notebook 与 Python 脚本之间的交互进行了设计。
另外,不要对来源不可信的 Python 文件随意使用 exec(),因为 exec() 会直接执行其中包含的代码。
三、使用 subprocess 调用 Python 解释器
第三种方式是通过 subprocess 模块启动一个独立的 Python 进程运行 .py 文件。
示例:
Python运行import subprocess result = subprocess.run( ["python", "test.py"], capture_output=True, text=True ) print(result.stdout)
如果当前系统中需要明确使用 python3,可以写:
Python运行import subprocess result = subprocess.run( ["python3", "test.py"], capture_output=True, text=True ) print(result.stdout)
这种方式和 %run 有一个非常明显的区别:subprocess 启动的是独立进程。
例如 test.py:
Python运行x = 100 print(x)
Notebook 执行:
Python运行import subprocess subprocess.run(["python", "test.py"])
虽然脚本会输出:
100
但脚本中的 x 并不会自动成为当前 Notebook 的变量:
Python运行print(x)
可能得到:
NameError: name 'x' is not defined
这是因为 Notebook 和 test.py 分别运行在不同的 Python 进程中。
获取脚本执行结果
如果需要获取 Python 文件的标准输出,可以使用:
Python运行import subprocess result = subprocess.run( ["python", "test.py"], capture_output=True, text=True ) print(result.stdout)
如果脚本执行失败,还可以检查返回码:
Python运行if result.returncode == 0: print("执行成功") else: print("执行失败") print(result.stderr)
这种方式非常适合测试独立 Python 程序,尤其是脚本本身依赖命令行环境、需要独立进程或者需要模拟生产运行方式时。
指定 Python 解释器
如果电脑上安装了多个 Python 版本,直接写 python 可能调用错误的解释器。这种情况下可以直接指定解释器路径:
Python运行import subprocess subprocess.run([ r"C:Python311python.exe", "test.py" ])
Linux 环境可以类似这样:
Python运行subprocess.run([ "/usr/bin/python3", "test.py" ])
这种方式对于解决 Python 环境混乱、虚拟环境与 Notebook 内核不一致等问题非常有帮助。
四、通过 Jupyter Notebook 的终端命令运行 Python 文件
Jupyter Notebook 还支持通过 ! 执行系统命令,因此可以直接调用 Python:
Python运行!python test.py
Linux 或 macOS 中也可以:
Python运行!python3 test.py
如果脚本路径包含空格,建议使用引号:
Python运行!python "my scripts/test.py"
这种方法实际上是在 Notebook 中调用系统 Shell 命令,使用起来非常接近在命令行窗口运行 Python 文件。
例如:
Python运行!python test.py
对应于操作系统终端中的:
Bashpython test.py
使用参数运行
同样可以传递参数:
Python运行!python test.py hello 123
如果 test.py 使用:
Python运行import sys print(sys.argv)
就可以看到传入的命令行参数。
使用当前 Notebook 的 Python 环境
相比直接写:
Python运行!python test.py
更推荐在需要确保解释器一致时使用:
Python运行import sys !{sys.executable} test.py
sys.executable 会获取当前 Notebook 内核所使用的 Python 解释器路径。
例如:
Python运行import sys print(sys.executable)
可能得到:
C:Usersusernaconda3envsmyenvpython.exe
然后:
Python运行!{sys.executable} test.py
就能够明确使用当前 Jupyter 内核对应的 Python 环境。
这一点对于 Anaconda、venv、conda 环境尤其重要,可以避免出现“Notebook 中可以导入某个库,但运行 Python 文件时却提示找不到模块”的情况。
四种方法如何选择
四种方法都可以在 Jupyter Notebook 中运行 Python 文件,但适用场景并不完全相同。
| 方法 | 是否独立进程 | 变量是否进入Notebook | 是否适合传参数 | 主要用途 |
|---|---|---|---|---|
%run test.py | 否 | 是 | 是 | Notebook中调试、测试脚本 |
exec() | 否 | 是 | 需要自行处理 | 动态执行Python代码 |
subprocess.run() | 是 | 否 | 是 | 独立运行Python程序 |
!python test.py | 是 | 否 | 是 | 快速执行系统命令 |
如果只是想快速运行一个 Python 文件,优先考虑:
Python运行%run test.py
如果希望脚本和当前 Notebook 环境共享变量,可以使用:
Python运行%run test.py
或者根据特殊需求使用:
Python运行exec(open("test.py", encoding="utf-8").read())
如果希望以独立 Python 程序的方式运行,则更适合:
Python运行import subprocess subprocess.run([sys.executable, "test.py"])
如果只是偶尔执行脚本或其他系统命令,可以使用:
Python运行!{sys.executable} test.py
Jupyter Notebook 中运行 Python 文件时的路径问题
实际使用过程中,最常见的问题之一并不是 Python 文件本身,而是文件路径。
可以使用下面的代码查看 Notebook 当前工作目录:
Python运行import os print(os.getcwd())
如果 test.py 不在这个目录,就需要使用正确的相对路径:
Python运行%run ./scripts/test.py
也可以使用绝对路径:
Python运行%run "D:/project/scripts/test.py"
Windows 路径建议使用正斜杠:
Python运行%run D:/project/test.py
或者使用原始字符串:
Python运行path = r"D:project est.py"
如果项目结构类似:
project/ ├── notebook/ │ └── demo.ipynb ├── scripts/ │ └── test.py └── data/ └── data.csv
Notebook 位于 notebook 目录时,可以运行:
Python运行%run ../scripts/test.py
但需要注意,脚本内部使用的相对路径通常与当前工作目录有关,而不是简单地以 .py 文件所在目录作为基准。因此,复杂项目中最好明确管理工作目录和资源路径。
如何解决“找不到 Python 文件”的问题
如果执行:
Python运行%run test.py
出现类似:
FileNotFoundError
首先检查当前工作目录:
Python运行import os print(os.getcwd())
然后查看当前目录中的文件:
Python运行os.listdir()
如果没有看到 test.py,说明脚本不在当前工作目录,需要调整路径。
也可以直接判断文件是否存在:
Python运行import os print(os.path.exists("test.py"))
返回:
True
说明路径正确;如果返回:
False
则需要检查文件名称、目录以及路径写法。
运行 Python 文件后修改代码为什么没有立即生效
有些情况下,用户修改了 .py 文件,再次执行时发现结果似乎没有按照预期变化。
对于普通 %run 操作,重新运行:
Python运行%run test.py
通常会重新读取并执行脚本。
如果使用的是模块导入方式,例如:
Python运行import test
那么 Python 会缓存已经导入的模块。修改 test.py 后再次执行:
Python运行import test
不一定会重新加载文件。
这种情况下可以使用:
Python运行import importlib import test importlib.reload(test)
因此,“运行 Python 文件”和“导入 Python 模块”是两个不同概念。需要反复调试脚本时,%run 往往比单纯 import 更直观。
推荐的实际使用方式
对于数据分析、机器学习和日常 Python 开发,Jupyter Notebook 通常负责实验和验证,而 .py 文件负责保存相对完整的程序逻辑。
例如项目中有:
project/ ├── analysis.ipynb ├── train.py ├── utils.py └── data/
Notebook 中需要快速测试训练脚本时,可以使用:
Python运行%run train.py
如果训练脚本需要参数:
Python运行%run train.py --epochs 20 --batch-size 32
如果希望完全按照独立程序的形式执行:
Python运行import subprocess import sys result = subprocess.run( [sys.executable, "train.py", "--epochs", "20"], capture_output=True, text=True ) print(result.stdout)
而对于只需要快速执行一次的脚本:
Python运行!{sys.executable} train.py
即可满足需求。
总结
Jupyter Notebook 中运行 Python 文件并不只有一种方式。%run 是最适合日常 Notebook 开发的方案,语法简单,并且能够方便地使用脚本中的变量和函数;exec() 更偏向动态执行 Python 源代码,灵活但需要注意安全性;subprocess 适合需要独立 Python 进程的场景,可以更接近真实命令行环境;!python 则适合快速调用系统命令。
如果主要目的是调试和分析 .py 文件,优先使用:
Python运行%run test.py
如果需要确保使用当前 Notebook 对应的 Python 环境,则可以采用:
Python运行import sys !{sys.executable} test.py
掌握这四种方法后,可以根据是否需要共享变量、是否需要独立进程、是否需要传递命令行参数以及 Python 环境是否一致等条件,选择最合适的运行方案。