Python相对导入报错:Attempted relative import with no known parent package 求助
问题场景
项目结构:
Project/ |-- __init__.py |-- utils/ | |-- __init__.py | |-- utils.py | |-- app/ | |-- main.py
遇到两个导入错误:
- 在
main.py中执行from .utils import utils,报错:ImportError: attempted relative import with no known parent package - 尝试
from utils import utils,报错:ModuleNotFoundError: No module named 'utils'
错误原因解析
相对导入报错原因
直接运行main.py时,Python会将app目录视为顶层执行脚本的目录,而非Project作为顶层包。此时main.py的__package__属性为空,相对导入(以.开头)需要基于已识别的父包,自然找不到utils所在的层级。
绝对导入报错原因
Python查找模块时,只会在sys.path列表中的目录里搜索。默认情况下,sys.path包含当前工作目录和Python标准库路径。如果直接运行main.py,当前工作目录是app(或者你运行脚本时的目录不是Project),utils包所在的Project目录不在sys.path里,所以找不到utils模块。
为什么sys.path.append('.')能临时解决?
如果运行main.py时的当前工作目录是Project,sys.path.append('.')就是把Project目录加入了搜索路径,此时Python能找到utils包。但这种方法不通用——如果换个目录运行脚本,'.'指向的路径变了,就会再次报错。
正确解决方案
方案1:用模块方式运行脚本
从Project目录的上级目录执行命令:
python -m app.main
这种方式会把Project目录加入sys.path,此时:
- 相对导入可以改为
from ..utils import utils(..表示向上一级包,即Project,utils是同级包) - 绝对导入
from utils import utils也能正常工作
方案2:设置PYTHONPATH环境变量
将Project目录的绝对路径添加到PYTHONPATH:
- Linux/macOS终端:
export PYTHONPATH="/path/to/Project:$PYTHONPATH" - Windows命令行:
set PYTHONPATH=C:\path\to\Project;%PYTHONPATH%
设置后,无论在哪运行main.py,Python都能找到utils包,直接用from utils import utils即可。
方案3:调整脚本位置或新增入口
把main.py移到Project根目录下,或者在根目录创建入口脚本run.py:
# Project/run.py from app.main import main_function # 假设main.py里有main_function函数 main_function()
然后从Project目录运行python run.py,此时sys.path包含Project,from utils import utils在main.py中也能正常使用。
内容的提问来源于stack exchange,提问作者vilal32

