Python中怎么看待一个 1000+行的__init__.py文件?

__init__.py中一般只是放 public interface,看到 pytest 这个 1000+行的__init__.py我真是醉了。。。。


Python中怎么看待一个 1000+行的__init__.py文件?

1 回复

这玩意儿就是个灾难。一个__init__.py文件堆到1000多行,通常意味着代码结构出了大问题。这文件的本意是初始化包,定义__all__,或者做一些轻量的导入,不是让你当垃圾场用的。

最常见的情况是把本该分散在模块里的类、函数、常量全塞这儿了,或者写了一大堆包内部的复杂初始化逻辑。这让你的包难以理解、测试和维护。想象一下,你想改个工具函数,得在上下个文件中翻找,而不是去一个清晰的utils.py模块。

核心建议就一个:重构,赶紧拆了它。

怎么拆?看情况。如果是堆了很多定义,就创建新的模块文件(比如models.py, services.py, constants.py),把代码移过去,然后在__init__.py里优雅地导入并暴露你需要公开的部分。如果是一大坨初始化代码,看看能不能移到专门的setup.py或一个core.py模块的函数里。

给你看个重构的例子。假设你原来有个恶心的mypackage/__init__.py,里面啥都有:

# 糟糕的 mypackage/__init__.py (部分示例)
CONST_A = 1
CONST_B = 2

def utility_helper():
    pass

class PrimaryClient:
    pass

class InternalParser:
    pass

def _private_setup():
    pass

# ... 还有好几百行

重构步骤:

  1. 创建模块:在mypackage/目录下新建文件,比如client.py, parsers.py, constants.py
  2. 迁移代码
    • PrimaryClient类移到client.py
    • InternalParser类移到parsers.py
    • CONST_A, CONST_B移到constants.py
    • utility_helper移到新文件utils.py或根据功能放入相应模块。
  3. 清理并简化 init.py:让它只做导入和暴露公共接口。
# 重构后干净的 mypackage/__init__.py
from .constants import CONST_A, CONST_B
from .client import PrimaryClient
# 只导入你想让用户直接从包名访问的东西
# 例如: from .parsers import InternalParser # 如果不公开,就别在这里导入

__all__ = ['CONST_A', 'CONST_B', 'PrimaryClient'] # 明确公开的接口

现在结构清晰多了:

mypackage/
├── __init__.py   # 变薄了,只做导入
├── client.py     # 放客户端相关类
├── parsers.py    # 放解析器
├── constants.py  # 放常量
└── utils.py      # 放工具函数

用户还是可以from mypackage import PrimaryClient,但背后的结构是清晰的。至于那些复杂的初始化代码,单独放到一个setup_module()函数里,在需要时显式调用。

总结:别忍,赶紧拆分成模块。

回到顶部