跳至主要內容

__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 包的控制中心,能实现:

  • 包标识与初始化
  • 导入路径优化
  • 模块暴露控制
  • 性能优化(懒加载)
  • 版本管理
    大厂偏爱原因:提升代码可维护性 + 规范项目结构 + 隐藏实现细节