Jupyter Notebook遇ModuleNotFoundError:如何兼顾模块与笔记本运行?
问题场景
文件结构如下:
my_directory modules # 只是普通目录,不是Python包 my_module_1.py my_module_2.py my_notebook.ipynb
my_module_2.py中导入my_module_1.py的代码:
# in my_module_2.py import my_module_1 as something
my_notebook.ipynb中导入my_module_2.py的代码:
# in my_notebook.ipynb import modules.my_module_2 as something from modules.my_module_2 import my_function
单独运行my_module_2.py一切正常,但运行笔记本代码时会触发ModuleNotFoundError:
ModuleNotFoundError Traceback (most recent call last) Input In [1], in <cell line: 1>() ----> 1 import modules.my_module_2 as something File ~\my_directory\modules\my_module_2.py:1, in <module> ----> 1 import my_module_1 as something ModuleNotFoundError: No module named 'my_module_1'
若修改my_module_2.py的导入语句为import modules.my_module_1 as something,笔记本可正常运行,但单独运行my_module_2.py时又会报错。
无需改动文件结构的解决办法
办法1:在笔记本开头添加路径到Python搜索路径
在笔记本的第一个代码单元格中,先把modules目录加入Python的系统搜索路径,确保my_module_2能找到my_module_1:
import sys from pathlib import Path # 获取当前笔记本所在目录,拼接modules路径 modules_path = Path.cwd() / "modules" sys.path.append(str(modules_path)) # 之后正常导入模块 import modules.my_module_2 as something from modules.my_module_2 import my_function
办法2:修改my_module_2.py,动态添加搜索路径
在my_module_2.py开头加入一段代码,自动将当前脚本所在的modules目录加入搜索路径,适配两种运行场景:
import sys from pathlib import Path # 获取当前脚本所在的modules目录 current_dir = Path(__file__).parent # 将该目录加入系统搜索路径 sys.path.append(str(current_dir)) # 原导入语句保持不变 import my_module_1 as something
办法3:将modules转为Python包(仅新增一个空文件)
如果可以接受在modules目录下创建一个空的__init__.py文件(不改变原有目录层级),可使用相对导入:
- 在
modules目录下创建空文件__init__.py,此时modules成为Python包 - 修改
my_module_2.py的导入语句为相对导入:
# in my_module_2.py from . import my_module_1 as something
- 单独运行
my_module_2.py时,需在my_directory目录下用模块方式启动:
python -m modules.my_module_2
内容的提问来源于stack exchange,提问作者Prown
相关产品推荐
相关产品推荐

