__init__.py解析
大约 2 分钟模块模块
🏗 先搞懂 Python 模块(Module)
在聊 __init__.py
之前,得先弄清楚 Python 里的 模块(Module) 和 包(Package) 概念:
📌 模块(Module):简单来说,就是一个 .py
文件,里面包含函数、类或变量。
例如 math_tools.py
文件:
def add(a, b):
return a + b
def subtract(a, b):
return a - b
调用方式:
import math_tools
print(math_tools.add(3, 5)) # 输出 8
📦 Python 包(Package)是啥?
当模块越来越多时,需要用 包(Package) 来组织代码:
- 一个包含多个模块(
.py
文件)的文件夹 - 在 Python 3.3 之前:必须包含
__init__.py
才能被识别为包 - Python 3.3+:无
__init__.py
也能识别为包(命名空间包),但实际项目强烈建议保留,因为可以:
✅ 明确标记目录为 Python 包
✅ 在包初始化时执行特定代码
✅ 控制导入行为,避免命名冲突
示例目录结构:
math_utils/ # Python 包
├── __init__.py
├── basic.py # 基础模块
└── advanced.py # 高级模块
🎭 init.py 的核心作用
1️⃣ 明确标记目录为 Python 包
存在 __init__.py
时,Python 解析器会识别:"这是个 Python 包,不是普通文件夹"。即使 Python 3.3+ 不强制要求,但保留它能:
- ✅ 避免解释器误判为普通目录
- ✅ 兼容旧版 Python
- ✅ 方便工具识别(如 pytest、mypy)
2️⃣ 让包像模块一样被导入
示例 1:直接暴露子模块
# math_utils/__init__.py
from .basic import add, subtract
from .advanced import power
调用方式:
import math_utils
math_utils.add(2, 3) # 直接调用
math_utils.power(2, 3) # 无需写 math_utils.advanced.power
示例 2:包初始化操作
# math_utils/__init__.py
print("数学工具包加载成功!") # import 时自动执行
🔥 init.py 的高级用法
✅ 1. 动态导入子模块
场景:避免手动维护大量导入语句
# math_utils/__init__.py
import os
import importlib
package_path = os.path.dirname(__file__)
for module in os.listdir(package_path):
if module.endswith(".py") and module != "__init__.py":
module_name = module[:-3] # 去掉.py后缀
importlib.import_module(f".{module_name}", __name__)
效果:
import math_utils # 自动加载所有子模块
math_utils.basic.add(1, 2) # 直接调用
✅ 2. 控制对外暴露的模块
用 __all__
限制 from package import *
的访问范围:
# math_utils/__init__.py
__all__ = ["add"] # 只暴露 add 函数
from .basic import add, subtract
✅ 3. 懒加载(Lazy Import)
场景:提升性能,延迟大模块加载
# math_utils/__init__.py
import importlib
def lazy_import(name):
return importlib.import_module(f".{name}", __name__)
advanced = lazy_import("advanced") # 使用时才加载
✅ 4. 版本控制
# math_utils/__init__.py
__version__ = "1.0.0"
调用方式:
import math_utils
print(math_utils.__version__) # 输出 "1.0.0"
✅ 5. 隐藏内部实现
# math_utils/__init__.py
from .basic import add # 只暴露 add 函数
__all__ = ["add"] # 隐藏 advanced 模块
关键结论:
🚀__init__.py
是 Python 包的控制中心,能实现:
- 包标识与初始化
- 导入路径优化
- 模块暴露控制
- 性能优化(懒加载)
- 版本管理
大厂偏爱原因:提升代码可维护性 + 规范项目结构 + 隐藏实现细节