Python自定义库开发 嵌套目录运行报ModuleNotFoundError
问题场景
开发Python自定义库阶段,测试文件放在非项目根目录运行时触发ModuleNotFoundError: No module named报错,测试文件移到项目根目录则可正常运行。
报错时目录结构
. └── project ├── library_directory │ ├── __init__.py │ └── main.py └── examples_directory ├── __init__.py └── code_directory ├── __init__.py └── test.py
相关文件代码
library_directory/__init__.py:
from library_directory.main import Class
examples_directory/code_directory/test.py导入语句:
from library_directory import Class
直接运行code_directory下的test.py即触发导入错误,可正常运行的目录结构为测试文件放在project根目录:
. └── project ├── library_directory │ ├── __init__.py │ └── main.py ├── examples_directory │ ├── __init__.py │ └── code_directory │ └── __init__.py └── test.py
已尝试绝对导入、相对导入方案,均未解决问题。
报错核心原因
直接运行子目录下的Python脚本时,Python默认会将脚本自身所在的目录加入模块搜索路径sys.path,不会自动识别项目根目录。在code_directory目录下运行test.py时,模块搜索路径中不存在project根目录,无法找到同级的library_directory模块,因此触发报错。测试文件放在project根目录时能正常运行,本质是此时脚本所在目录刚好是项目根目录,处于搜索路径范围内。
可行解决方案
方案1:临时添加项目根目录到搜索路径(开发调试最快)
在test.py最顶部、所有自定义库导入语句之前,添加代码将project根目录加入模块搜索路径,原有导入逻辑无需修改:
import sys from pathlib import Path # 向上3级取到project根目录,根据实际目录层级调整parent数量即可 sys.path.append(str(Path(__file__).parent.parent.parent.resolve())) # 原有导入语句正常写 from library_directory import Class
层级计算逻辑:
__file__指代当前test.py文件路径,1级parent是code_directory,2级parent是examples_directory,3级parent就是project根目录。
方案2:以模块模式运行脚本(零代码修改)
不要直接在code_directory目录下运行test.py,先切换终端工作路径到project根目录,使用-m参数以模块路径形式运行脚本:
# 先进入project根目录 cd /your/absolute/path/to/project # 以模块方式运行测试文件 python -m examples_directory.code_directory.test
该运行方式下Python会自动将当前终端所在的project根目录加入模块搜索路径,无需修改任何代码即可正常导入。
方案3:可编辑模式安装本地库(长期开发最规范)
如果是长期开发该自定义库,在project根目录新建最小配置的pyproject.toml文件:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "your-custom-library" version = "0.0.1" packages = ["library_directory"]
在project根目录下执行安装命令:
pip install -e .
安装完成后,当前Python环境会永久识别该本地库,无论测试脚本放在项目哪个子目录下,都可以直接正常导入library_directory,和使用第三方库的体验完全一致,不需要额外加路径配置。
内容的提问来源于stack exchange,提问作者Matias Martinez

