__init__.pyの必要性

この記事の目的は、Pythonにおける__init__.pyが必要なケースと不要なケースを
具体例で検証することです。

パッケージをimportできるようにするために__init__.pyが必要とよく言われますが、
Python 3.3以降ではそれが無くてもimportできてしまうことに触れます。
(何故なら私がハマったからです・・・)

前提

  • OS: Ubuntu 16.04
  • Python 3.2.6 / 3.6.7で動作確認

サマリ

  • パッケージをimportしたいだけであれば、Python 3.3以降は__init__.pyがなくてもimportできる
  • (上記ケースにおいて)3.2以前は必要
  • import時に初期化処理を行う目的で__init__.pyを使うならば、Python3.3以降以前関係なく、必要
  • __init__.pyなしのパッケージは名前空間パッケージであり、通常のパッケージとは異なる
  • 明確に名前空間パッケージを使いたいケース以外は通常パッケージにしておくほうが良い?(下記リンク)

__init__.pyの基本の確認

__init__.pyを使う上でよく言われることは以下です。

  1. __init__.pyをディレクトリに置いておくとそのディレクトリはパッケージとして扱われる
  2. __init__.pyにパッケージの初期化処理を書いておくと、import時に実施される

2.でやることが無いのであれば、__init__.pyは中身は空で構いません。
Python 3.2.6で具体例で見てみます。

1
2
3
4
5
6
# ディレクトリ構成
(python3.2.6)$ tree
.
├── main.py
└── mypkg
└── mylib.py
1
2
3
4
# mylib.py
class Hoge:
def hello(self):
print('Hello!')
1
2
3
4
5
# main.py
from mypkg.mylib import Hoge

h = Hoge()
h.hello()

これでmain.pyを実施すると以下の通りエラーになります。__init__.pyがないのでimportできません。

1
2
3
4
5
(python3.2.6)$ python main.py
Traceback (most recent call last):
File "main.py", line 1, in <module>
from mypkg.mylib import Hoge
ImportError: No module named mypkg.mylib

しかし、mypkgディレクトリに__init__.pyを作成すると問題は解消します。touchは空ファイルを作成するコマンドです。

1
2
3
(python3.2.6)$ touch mypkg/__init__.py
(python3.2.6)$ python main.py
Hello!

Python 3.3以降では__init__.pyがなくてもimportできる

Python 3.3以降では空の__init__.pyが無くても名前空間パッケージとして認識され、import可能です。
https://www.python.org/dev/peps/pep-0420/

Python 3.6.7で試してみます。__init__.pyは削除済です。

1
2
3
4
5
6
7
8
(python3.6.7)$ tree
.
├── main.py
└── mypkg
└── mylib.py

(python3.6.7)$ python main.py
Hello! # No import error

私の場合、3.3前後でこのような違いがあることを知らず、
ある偶然で__init__.pyを作り忘れても普通にimportできてしまった時に混乱し、色々と調べてみたのがこの記事の発端です。

参考リンク