Python项目标记模块后跨目录导入报ModuleNotFoundError问题排查
问题根本原因
Python导入模块时会优先查找sys.path列表中的路径,直接执行python app/main.py时,Python会自动将脚本所在的目录(即foo/app)添加到sys.path,你当前的工作目录foo不会被加入到搜索路径中,因此无法定位到顶层的app模块。
不同运行场景的逻辑说明
- 可正常运行的场景:
main.py使用from folder1.aaa import X导入时,folder1直接位于foo/app目录下,正好在sys.path的搜索范围内,因此可以正常找到模块。 - 报错场景1、2:使用
from app.xxx.xxx import ...格式导入时,需要foo目录在sys.path中才能找到app模块,此时搜索路径中没有foo目录,因此直接抛出ModuleNotFoundError。
解决方案
推荐按优先级选择以下方案:
- 使用-m参数以模块形式运行入口脚本(最推荐)
在foo目录下执行命令:
python -m app.main
该执行方式会自动将当前工作目录(foo)加入sys.path,完全符合Python的包管理规范,所有绝对导入、相对导入逻辑都可以正常生效。
- 手动将项目根目录添加到sys.path
在入口脚本main.py的最开头添加以下代码,自动把foo目录加入搜索路径:
import sys from pathlib import Path # 取当前文件的父目录的父目录,即foo目录的绝对路径 sys.path.append(str(Path(__file__).parent.parent.resolve()))
添加后再执行python app/main.py即可正常运行。
- 包内部导入改为相对导入
包内的文件互相导入时可以使用相对路径写法,避免依赖顶层模块名,例如aaa.py中导入bbb.py可以写为:
from ..folder2.bbb import Y
注意相对导入只允许在包内部的模块中使用,入口脚本如果使用相对导入需要配合-m参数运行。
内容的提问来源于stack exchange,提问作者Jean Toniolli
相关产品推荐
相关产品推荐

