Python3.9包相对导入失效报超出顶级包错误问题咨询
问题原因
- Python的包相对导入不支持在直接运行的顶层脚本中解析。当你执行
python c.py时,Python会把c.py标记为顶层入口模块(__name__ = "__main__"),不会为它维护包层级关系。此时b.py里的from ..dir1.a import a_foo尝试向上回溯两层找父包,已经超出了Python识别到的顶层包边界,直接抛出attempted relative import beyond top-level package错误。 - 你标注所有初始化文件命名为
__init.py__,这里存在文件名错误:Python识别正规包要求目录下的初始化文件名为__init__.py(init和py之间有一个半角句号),文件名写错会导致Python无法将对应目录识别为包,同样会触发导入异常。
修复方案
二选一即可,优先选第一种,对现有代码改动最小:
方案1:用模块模式启动脚本
不要进入存放c.py、dir1、dir2的目录直接运行脚本,退到该目录的上一级路径,用-m参数以模块模式启动。
比如你当前c.py存放在D:\tmp\py路径下(和报错里的路径一致),就在D:\tmp路径下执行命令:
python -m py.c
如果你实际的代码是存放在嵌套的lib目录下(即路径为D:\tmp\py\lib\c.py,和你最开始写的目录结构一致),就在D:\tmp\py路径下执行python -m lib.c即可。这种启动方式会让Python完整识别整个目录的包层级,内部的相对导入会按规则正常解析。
方案2:把启动脚本移到包外层
调整目录结构,把所有包内代码收敛到独立的包目录,启动脚本放在包的同级路径,参考结构如下:
your_project/ start.py # 启动脚本放在包外 my_package/ # 原来的代码都放到这个包目录下 __init__.py dir1/ __init__.py a.py dir2/ __init__.py b.py c.py
start.py中写入导入逻辑:
from my_package.dir2.b import b_bar print(b_bar())
之后在your_project路径下直接执行python start.py即可,此时my_package是识别到的顶层包,内部相对导入不会越界。
注意:不要通过手动修改
sys.path的方式强行适配导入路径,这种方式会破坏Python默认的模块解析规则,项目规模变大后极易出现模块重复加载、版本冲突等难以定位的问题。
内容的提问来源于stack exchange,提问作者Qiao Li
相关产品推荐
相关产品推荐

