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
# ... 还有好几百行
重构步骤:
- 创建模块:在
mypackage/目录下新建文件,比如client.py,parsers.py,constants.py。 - 迁移代码:
- 把
PrimaryClient类移到client.py。 - 把
InternalParser类移到parsers.py。 - 把
CONST_A,CONST_B移到constants.py。 - 把
utility_helper移到新文件utils.py或根据功能放入相应模块。
- 把
- 清理并简化 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()函数里,在需要时显式调用。
总结:别忍,赶紧拆分成模块。

