Python 3.3+ 支持隐式命名空间包(PEP 420),使 __init__.py 不再是 import 的硬性前提,但相对导入、from ... import *、打包工具、测试框架及类型检查器等仍依赖其存在,空 __init__.py 是最简兼容方案。

Python 3.3+ 支持隐式命名空间包,所以 __init__.py 不再是 import 的硬性前提
根本原因不是“放宽限制”,而是解释器在 import 时新增了对隐式命名空间包(PEP 420)的支持。当它找不到带 __init__.py 的目录时,不会立刻报错,而是继续检查:该路径是否纯为子模块集合、是否无同名普通文件(如 mypkg.py)、多个同名目录是否分散在不同 sys.path 位置——满足就拼成一个逻辑包。
省略 __init__.py 后,import mypkg 可能成功,但 from mypkg import * 和相对导入会直接失败
常见错误现象包括:
-
SystemError: Parent module '' not loaded或ImportError: attempted relative import with no known parent package—— 只要代码里有from ..utils import x或from . import sibling,当前文件所在目录和目标模块所在目录都必须有__init__.py(哪怕为空) -
from mypkg import *不导入任何东西,因为没__all__定义入口,也没__init__.py做显式导入 - 空
__init__.py就足以启用相对导入;删掉它,哪怕目录结构完全一样,也会崩
打包工具、测试框架和类型检查器普遍不信任无 __init__.py 的目录
现实工程中踩坑最多的地方:
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
-
pytest默认只把含__init__.py的目录当包处理,否则test_*.py可能被忽略 -
mypy、pyright对隐式命名空间包支持不稳定,常报Unable to resolve import -
PyInstaller、cx_Freeze默认不扫描无__init__.py的目录,容易漏模块 - 用
python -m mypkg.cli运行时,解释器无法识别该目录为包,直接报ModuleNotFoundError
空 __init__.py 是最便宜的兼容性保险
它不增加运行时开销,却能堵住绝大多数导入链断裂点:
立即学习“Python免费学习笔记(深入)”;
- 让
import mypkg、from mypkg import x、from mypkg.sub import y全部稳定工作 - 为将来加初始化逻辑(比如注册插件、预加载配置)留出接口,不用改导入路径
- 避免团队成员本地 Python 版本(如 3.9)和 CI 环境(如 3.12)之间因隐式包行为差异导致的不一致
- IDE 补全、跳转、重命名等基础功能依赖它做包边界判定,缺了就卡顿或失效
真正需要隐式命名空间包的场景极少——比如跨仓库拼接插件目录,或者构建高度动态的插件系统。日常开发里,放一个空 __init__.py 比事后花半天查 ImportError 根源划算得多。

















