Python 模块的魔法入口——__init.py__ 实战指南

我们在使用 python 库的时候会发现库内很多文件夹下都有一个__init__.py文件,有时候一个库里所有的代码都写在里面,有时候就是一个空文件,非常迷惑。

今天我们就来聊聊 Python 模块的入口__init__.py

开门见山的说,__init__.py 的职责只有一个:把目录变成包,但“里面写不写东西、写多少”完全取决于你想让包长成什么样。

假设你的包名是 mypkg,下面给出一套“从简到繁”的最佳实践清单,按需取用即可。


  1. 最简单的空文件
    什么都不写也能让 import mypkg 成功。适合一次性脚本或内部工具。
# mypkg/__init__.py(空文件即可)

  1. 暴露公共 API(99 % 的库都要)
# mypkg/__init__.py
from ._core import run_counter# 内部实现
from ._types import CounterResult # 公开的数据类

__all__ = ["run_counter", "CounterResult"] # 控制 from mypkg import * 的行为
__version__ = "1.2.0"# 方便 mypkg.__version__

要点
• 只在 __init__.py 里放“用户需要直接用的名字”,其余留作内部模块。
• 用 __all__ 明确导出,静态检查工具(mypy、pyright)也省心。

如果不配置__all____version__会怎么样?

只写这两行,包可以正常被 Python 识别,但会出现几个“副作用”:

  1. 任何 from mypkg import * 会一股脑把 run_counter 和 CounterResult 都导出去
    因为没有 all,所以星号导入会把当前命名空间里所有非下划线开头的名字全带走(这里刚好就是那两个,所以没有影响)。多数情况下这不是你想要的,因为以后再加内部变量也会被导出。
  2. IDE / 静态检查器(mypy、pyright)
    它们依旧能找到 mypkg.run_counter,所以开发体验没问题;
    但缺少 all 会让静态工具在“哪些符号是公有”这件事上给出更宽松的提示。
  3. 没有 version 等元数据
    用户无法 import mypkg; print(mypkg.__version__),发布到 PyPI 时也不符合常见约定。
  4. 没有懒加载、日志初始化等高级需求
    如果包很小,这些可以忽略;中大型库通常需要。

  1. 延迟加载 & 子包懒导入(中大型库)
# mypkg/__init__.py
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    # 仅给类型检查器看
    from . import utils, io, plot

__all__ = ["run_counter", "plot"]
__version__ = "1.2.0"

# 运行时再真正 import,降低启动开销
def __getattr__(name: str):
    if name == "run_counter":
        from ._core import run_counter as rc
        return rc
    raise AttributeError(f"module {__name__} has no attribute {name}")

  1. 配置 logging、插件注册、元数据
# mypkg/__init__.py
import logging
from importlib.metadata import version

__version__ = version("mypkg")

# 默认给库打日志,但不污染用户根 logger
logging.getLogger(__name__).addHandler(logging.NullHandler())

# 自动注册插件(若需要)
from . import _plugins; _plugins.register()

  1. 可选:设置 __path__(高级)

当你想把一个大包拆成多个物理目录(namespace package),才需要去动 __path__,99 % 的情况不需要。


简单总结一下

__init__.py 就是包的“门面”。
• 只想让目录可导入 → 空文件。
• 想做库 → 至少写 __version__ 和公开 API。
• 想优化启动或做复杂结构 → 加懒导入、日志、插件注册等。

posted @ 2025-07-16 01:45  GOKORURI  阅读(322)  评论(0)    收藏  举报