
ythonで開発をしていると、フォルダ内に __init__.py というファイルがあるのをよく見かけます。特に、自作モジュールやパッケージを構成する際には欠かせない存在です。しかし、なぜこのファイルが必要なのか、最近のPythonでは必要ない場面もあるのかなど、意外と曖昧なまま使っている方も多いのではないでしょうか。
本記事では、「モジュール」「パッケージ」「ライブラリの構成」を整理しながら、__init__.py の役割を解説します。
1. Pythonの基本構造:モジュール・パッケージとは?
● モジュール(module)
単一の Pythonファイル(.py) のこと。例:math.py
# sample.py
print("hello")
これを import sample で読み込むのが“モジュール”。
● パッケージ(package)
複数のモジュールをまとめた フォルダ構成 のこと。そのフォルダに
__init__.py
が入っていると、そのフォルダは「パッケージ」として認識されます。
● ライブラリ(library)
複数のパッケージを含む大きなまとまり(requestsやnumpyなど)。
パッケージ → 集まり → ライブラリという階層イメージです。
2. __init__.py が必要な理由
① フォルダを“パッケージ”として認識させるため
Python 3.3より前は、__init__.py がないとフォルダはパッケージと見なされませんでした。 つまり:
myapp/
utils/
helper.py
となっている場合、utils に __init__.py がないと、
import utils.helper
が エラーになる 時代があったのです。
現在でも、明示的に“これはパッケージです”と示す意味で入れるのが一般的です。
② サブモジュールをまとめて公開できる
__init__.py 内で import を記述すると、外部からアクセスしやすくできます。
例:
myapp/
utils/
__init__.py
math_utils.py
string_utils.py
__init__.py に以下を書く:
from .math_utils import add, subtract
from .string_utils import to_upper
すると使用側では:
from utils import add, to_upper
と、シンプルに使えるようになります。
③ パッケージ初期化処理を書ける
パッケージが import された瞬間に実行したい処理を書くことも可能です。
# __init__.py
print("utils package loaded")
※実務ではあまり使いませんが、設定ロードやログの初期化に使われる場合があります。
3. Python 3.3以降は “なくても動く”?
Python 3.3から「namespace package」という仕組みが追加され、 __init__.py がなくてもパッケージとして扱われる場合があります。
しかし実務では:
-
依存ツール(mypy、pytest、IDE補完など)が
__init__.pyありを前提に動く -
namespace package の挙動はやや複雑
という理由から、基本的に入れるのが推奨です。
特に自作パッケージをGitHubで公開する場合、__init__.py を省略すると思わぬ不具合が出ることもあります。
4. 結論:__init__.py は“書かなくても動くことはあるが、入れた方が安心”
● 必須ではない場合が増えてきた(Python 3.3+)
● でも以下のメリットが大きい:
-
パッケージとして明示できる
-
import の整理がしやすい
-
ツール類との相性が良い
-
他プロジェクトでも一般的な慣例
特別な理由がない限り、空ファイルでよいので必ず配置すること を強くおすすめします。
5. 最小構成サンプル
myapp/
__init__.py
main.py
utils/
__init__.py
helper.py
どちらの __init__.py も空でOK。 これだけでPythonのパッケージ構造として正しく認識されます。
まとめ
-
__init__.pyはパッケージ宣言の役割を持つ重要なファイル -
Python 3.3以降は必須ではないが、実務ではほぼ必ず入れる
-
import の整理、補完、静的解析などにも有効
Pythonのコードを整理して規模を大きくしていくほど必要性が高まるので、ぜひ適切に活用してみてください。