ImportError:如何从父目录导入函数或类
报错核心原因
触发attempted relative import with no known parent package的本质是Python的相对导入完全依赖模块的__name__属性解析包层级:
- 如果你直接运行
c.py(比如执行python B/c.py或者进入B目录执行python c.py),此时c.py的__name__会被设为__main__,Python无法识别它属于B子包,更无法识别上层的包结构,所有相对导入语句都会直接失效。 - 你之前写的
from ..A.a import class1本身路径也存在错误:c.py位于A/B/路径下,..已经指向B的父目录也就是A目录根,再加A相当于查找A/A/a.py,路径层级完全不匹配。
可落地解决方法
根据你的运行场景选下面任意一种方案即可:
方案1(推荐,符合Python包规范):修正相对导入+以模块模式运行
- 先把
c.py里的错误导入语句替换为正确的相对导入:
from ..a import class1
- 退出到A文件夹所在的上一级目录,不要进入A或者B目录,用
-m参数以模块形式运行脚本:
# 假设你的A文件夹存放在~/project/路径下,即路径为~/project/A/ cd ~/project/ python -m A.B.c
这种运行方式下Python会完整识别整个A的包结构,c.py的__name__为A.B.c,相对导入的层级可以正常解析,不会触发报错。
方案2(适合单脚本直接运行):修正sys.path+绝对导入
如果你需要直接运行c.py文件,不想使用模块运行命令,就放弃相对导入写法,在c.py所有业务导入语句之前,把A目录的路径加入Python搜索路径,直接用绝对导入:
import sys from pathlib import Path # 把当前c.py文件的上上层目录(也就是A目录根)加入搜索路径 sys.path.append(str(Path(__file__).parent.parent.resolve())) # 直接从a模块导入目标类,不要加相对导入的.前缀 from a import class1
你之前加sys.path后仍报错,核心原因是加完路径后还保留了带..的相对导入写法,路径解析逻辑冲突。
避坑提示
- 只要脚本是被直接运行、
__name__ == '__main__',脚本内的相对导入就必然失效,这是Python的原生设计,不是环境配置问题。 - 写相对导入时先明确层级:单个
.代表当前脚本所在目录,两个..代表上一级目录,不要在..后重复写已经指代过的父目录名。 - 手动修改
sys.path的代码必须放在所有业务导入语句之前,否则Python会先执行模块查找,后续再加路径不会生效。
内容的提问来源于stack exchange,提问作者user59419
相关产品推荐
相关产品推荐

