Python多层级模块导入报ModuleNotFoundError,如何兼容不同层级运行?
问题根因
Python导入模块时会从sys.path列表存储的路径中查找目标包/模块,你的报错本质是不同脚本运行时的工作目录不同,导致模块搜索路径不匹配:
- 运行
Test.py时,执行脚本的工作目录是项目根目录Demo/,该路径会自动加入sys.path,可以直接找到z1包,所以运行正常 - 运行
Foo.py时,执行脚本的工作目录是Demo/z1/,该路径加入sys.path,但z1包本身存放在更上层的Demo/目录下,自然找不到z1模块
可行解决方案
方案1:统一以项目根目录为工作目录运行所有脚本(推荐,无需修改代码)
不要直接在z1目录下运行Foo.py,回到项目根目录Demo/,用模块方式执行:
python -m z1.Foo
此时工作目录仍然是Demo/,导入逻辑和Test.py完全一致,两个脚本都可以正常运行。
方案2:给Foo.py添加上层目录搜索路径
如果需要支持直接在z1目录下运行Foo.py,可以在Foo.py的所有导入语句前加入以下代码,手动把项目根目录加入模块搜索路径:
import sys, os sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
这段代码会自动获取Foo.py所在目录的上层目录(也就是Demo/),加入sys.path后后续导入语句就能正常识别z1包了。
方案3:使用相对导入(仅适用于包内模块调用场景)
如果Foo.py本身仅作为包内模块被上层调用,不需要作为入口脚本直接运行,可以把Foo.py里的导入语句改成相对导入:
from .z2.Screen import *
注意该方式下不能直接运行Foo.py,仅支持被上层模块导入使用,比如在Test.py中执行import z1.Foo时可以正常运行。
关于z2/init.py的导入说明
你当前写的from z1.z2.Screen import *不需要修改,只要保证运行脚本时项目根目录在sys.path中,两种运行场景都可以正常识别该导入路径。
内容的提问来源于stack exchange,提问作者Llosgfynydd
相关产品推荐
相关产品推荐

