根本原因是Python只在sys.path列出的目录中搜索模块,而当前脚本所在目录不自动包含在内;常见诱因包括执行位置错误、IDE工作目录设置不当、包结构缺失__init__.py、-m运行路径不对;推荐方案是pip install -e .将项目安装为可编辑包,使Python从一开始就识别包结构。

为什么 import 自定义模块总报 ModuleNotFoundError
根本原因不是代码写错了,而是 Python 解释器压根没在它搜索路径里找到那个模块。Python 只查 sys.path 列表里的目录,而当前脚本所在目录(os.getcwd())**并不自动包含在内**——除非你恰好从模块所在目录运行脚本。
常见诱因包括:python script.py 从项目根目录外执行、IDE 工作目录设错、包结构不满足导入规则、用 python -m 运行时入口位置不对。
用 sys.path.append() 临时加路径最直接但有隐患
适合快速验证或小脚本调试,但不推荐进正式代码或部署环境。
- 必须在
import语句之前执行,且路径要写对:用os.path.abspath()或pathlib.Path(__file__).parent构造绝对路径,避免相对路径失效 - 重复添加会导致
sys.path膨胀,可能引发同名模块加载错乱 - 打包成
exe(如 PyInstaller)后,__file__指向临时解压路径,硬编码路径会崩 - 示例:
import sys from pathlib import Path sys.path.append(str(Path(__file__).parent / "utils")) import mytool # 现在能找到了
用 python -m 运行并配合 __init__.py 做正确包导入
这是符合 Python 包机制的正解,尤其适合多层目录结构。
立即学习“Python免费学习笔记(深入)”;
- 确保每个子目录下都有
__init__.py(哪怕空文件),否则 Python 不认它是包 - 必须从**包的父目录**执行
python -m package.subpackage.module,不能在包目录里直接python module.py - 相对导入(
from . import xxx或from .. import yyy)只在模块被-m方式加载时才有效;直接运行会报SystemError: Parent module not loaded - 如果模块里混用绝对和相对导入,注意顶层包名要和命令中写的完全一致(区分大小写、拼写)
长期项目该用什么方案
开发阶段用 pip install -e . 安装为可编辑包,一劳永逸解决路径问题。
- 项目根目录放
setup.py或pyproject.toml,定义好name和packages - 终端切到项目根目录,执行
pip install -e .,Python 就会把当前目录“注册”进sys.path - 之后任何地方都能用
import正常导入,IDE 自动补全也正常,CI/CD 部署时也能复用这套配置 - 注意:虚拟环境必须激活后再装,否则会污染全局 Python 环境
相对导入看着简洁,但一旦运行方式不对就立刻失效;sys.path 手动加路径像创可贴,治标不治本。真正省心的方式,是让 Python 从一开始就“认识”你的包结构。


















