はじめに
pythonでパッケージ化をする必要が出てきたので、__init__.pyの書き方を調べました。
技術的な背景や経緯は不要で、とりあえず書き方だけを知りたかったのですが、簡単に理解できるような記事がすぐに見つかりませんでした。
そこで、備忘として簡単な説明を残します。
Python 3.3以降に限定
自身で書くPythonコードは常にPython3ですので、python2との互換性は日頃から一切考慮しません。また、基本的に新しい環境を使うようにしているため、Python 3.3より古い環境を考慮することがないので、Python 3.3以降に限定して説明します。
Python 3.3からは空の __init__.py は不要
__init__.py についで調べると必ず、中身が空っぽの__init__.pyに関する説明が出てくると思います。
「空で良いなら無くても動作するようにして」、と誰もが思うと思いますが、3.3からは空の__init__.pyを書かなくても、今まで空の__init__.pyを書いた時と同じように動作するようになりました。
ですので、空の__init__.pyのことはもう忘れましょう。
pep-420-implicit-namespace-packages
Native support for package directories that don’t require __init__.py marker files and can automatically span multiple path segments (inspired by various third party approaches to namespace packages, as described in PEP 420)
__init__.pyを用意したい時、用意した方が良いのはどんな時?
複数のファイルで流用したい共通処理を別ファイルに切り出して、'util'や'common'といったフォルダにまとめておく、というようなことはよくあることだと思います。
このような時には、そのフォルダに、__init__.pyを用意した方が良いでしょう。
__init__.pyには何を書けばよいか?
以下、実際に私が直面した事例で説明します。
svm.py というメインのファイルがあり、同じ階層に'util'というフォルダがあります。
'util'というフォルダには、training_data.pyとfile.pyがあります。
./svm.py
./util/training_data.py
./util/file.py
__init__.pyを用意しない場合、svm.pyでのimportは以下のようになります。
import util.training_data
import util.file
importに関しては、さほど不便は感じませんでしたが、実際にtraining_data.pyの中で実装されたTrainingDataというクラスをsvm.pyで使うには、次のように書く必要があり、煩わしく思いました。
training_data = util.training_data.TrainingData()
どう考えても、真ん中の'training_data.'を省略したくなりますね。
そこで、'util'フォルダに__init__.pyを用意します。
./svm.py
./util/training_data.py
./util/file.py
./util/__init__.py
そして以下を記述します。
#!/usr/bin/env python3
from util.file import *
from util.training_data import *
これにより、svm.pyでのimportは以下の1行で済むようになります。
import util
ファイル名を指定する必要がなくなり、utilをパッケージとして扱えるようになります。
また、util内のオブジェクト・関数呼び出しにおいても、ファイル名の指定が不要になります。
training_data = util.TrainingData()
あるいは、次のようにimportして使うこともできます。
from util import TrainingData
training_data = TrainingData()
まとめ
__init__.pyの使用目的は他にもあると思いますが、パッケージ化の仕方について簡単に説明してみました。