使用 __init__.py

67 投票
2 回答
42577 浏览
提问于 2025-04-15 19:54

我在理解 Python 中 __init__.py 文件的使用场景或设计目标时遇到了一些困难。

假设我有一个名为 'model' 的文件夹(可以看作一个包),里面包含以下文件:

  1. __init__.py
  2. meta.py
  3. solrmodel.py
  4. mongomodel.py
  5. samodel.py

我发现 __init__.py 有两种使用方式:

  1. 我有一些通用的定义,需要在 solrmodel.pymongomodel.pysamodel.py 中使用。我可以把 __init__.py 当作所有 *model.py 类的基础/公共定义吗?这意味着我需要导入 model/__init__.py

  2. 或者,__init__.py 可以在里面导入 solrmodel.pymongomodel.pysamodel.py 的定义,这样就可以很方便地像这样导入类或函数:

    # file: __init__.py
    
    from mongomodel import *
    from solrmodel import *
    from samodel import *
    

    (我知道 import * 并不推荐使用,我只是用它作为一种习惯)

我无法在这两种场景之间做出决定。__init__.py 还有其他使用场景吗?能不能解释一下它的用法?

2 个回答

23

当你在包里面导入一个模块时,__init__.py里的内容会被导入进来。

你可能忽略了第三种情况,就是把一些公共的部分放在一个单独的模块里,然后让其他模块去导入这个公共模块,这样__init__.py就可以用来放一些在包外部需要用到的东西。这是我通常遵循的做法。

52

我写的大多数 __init__.py 文件都是空的,因为很多包其实没有什么需要初始化的内容。

有一个例子是,当我加载这个包的时候,可能想一次性读取一些数据(比如从文件、数据库或者网络上),在这种情况下,把读取数据的代码放在包的 __init__.py 里一个私有函数中要比单独写一个“初始化模块”要好得多。这样就不用在包里的每个模块里重复导入那个初始化模块,这样做不仅麻烦,还容易出错。显然,依赖语言的特性保证包的 __init__.py 在包里的任何模块之前只加载一次,这样的做法更符合 Python 的风格!

如果你想了解更多具体和权威的观点,可以看看 Python 标准库中不同包的做法。

撰写回答