Python从子文件夹导入上层本地模块触发ModuleNotFoundError问题咨询
解决Python子目录脚本导入根目录模块报错问题
报错原因
Python导入模块时会优先搜索sys.path列表中存储的路径:
- 运行
caller1.py时,当前工作目录(项目根目录)会被自动加入sys.path,因此可以直接找到同级的helper.py - 运行
./sub_folder/caller2.py时,默认被加入sys.path的是sub_folder的路径,项目根目录不在搜索范围内,因此找不到helper模块
解决方案
下面是几种不同适用场景的解决方法:
方案1:代码内临时添加搜索路径(快速适配)
在caller2.py的最开头添加如下代码,将项目根目录动态加入搜索路径,后续即可正常导入:
import sys import os # 计算当前文件的上级目录(即项目根目录)的绝对路径,加入模块搜索路径 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from helper import hello if __name__ == '__main__': hello()
该方案无需修改系统配置,代码写完直接可运行,适合临时测试、单文件快速适配的场景。
方案2:配置PYTHONPATH环境变量(个人开发常用)
将项目根目录的绝对路径加入系统的PYTHONPATH环境变量,Python启动时会自动把该路径加入模块搜索列表,所有项目内的脚本都可以直接导入根目录下的模块:
- Windows系统:在系统环境变量中新建变量
PYTHONPATH,值填写项目根目录的绝对路径,保存后重启终端生效 - Linux/macOS系统:在
~/.bashrc(或~/.zshrc,根据所用终端类型决定)末尾添加export PYTHONPATH="你的项目根目录绝对路径:$PYTHONPATH",保存后执行source ~/.bashrc(或对应配置文件)生效
方案3:将项目构造成标准可安装包(多人协作/项目发布最优)
这是Python项目最规范的组织结构,适合长期维护、多人协作或者需要打包分发的项目:
- 在项目根目录新建
pyproject.toml配置文件,基础内容如下:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "你的项目名" version = "0.1.0"
- 在项目根目录、所有子文件夹下都新建一个空的
__init__.py文件,标记目录为Python包 - 在项目根目录执行命令
pip install -e .,将项目安装为开发模式,之后所有环境下都可以直接导入项目内的任意模块。
方案4:使用相对导入+模块方式运行
如果不想修改路径配置,也可以使用相对导入语法,但是运行脚本的时候需要用模块模式启动:
- 修改
caller2.py的导入语句为:
from ..helper import hello if __name__ == '__main__': hello()
- 运行时需要在项目根目录执行命令:
python -m sub_folder.caller2
注意不能直接进入sub_folder目录执行python caller2.py,否则会触发相对导入的层级错误。
内容的提问来源于stack exchange,提问作者T Pol
相关产品推荐
相关产品推荐

