import *
と __init__.py
の __all__
の関係
「Python チュートリアル」の「6.4.1. パッケージから * を import する」を読むと、__init__.py
中に __all__
という変数を定義することで、from some_package import *
とした場合に読み込まれるモジュールを制御できることが分かります。
例として、以下のパッケージ構成で考えます。
some_package/__init__.py
some_package/hoge.py
some_package/piyo.py
some_package/fuga.py
次のように some_package/__init__.py
に __all__
を定義します。
__all__ = ['hoge', 'piyo']
この場合に from some_package import *
とすると、some_package.hoge
と some_package.piyo
はインポートされますが、some_package.fuga
はインポートされません。
import *
でパッケージ内の全モジュールをインポートさせたい
細かく制御したい場合は __all__
に手作業でモジュール名を指定すれば良いのですが、from some_package import *
としたときに「パッケージ内の全モジュールをインポートさせたい」「パッケージ内にモジュールを増やしたときに手作業で __all__
に追加するのは面倒」という場合もあると思います。
そういう場合は、__all__
を以下のように定義しておくことで、自動的に追従することができます。
import os, glob
__all__ = [
os.path.split(os.path.splitext(file)[0])[1]
for file in glob.glob(os.path.join(os.path.dirname(__file__), '[a-zA-Z0-9]*.py'))
]
他の人が作ったパッケージの場合
他の人が作ったパッケージの場合は、上記のように対応できないかもしれません。そのときは以下のような関数を作成し、import_submodules(some_package)
とすることで対応できます。
import os, glob, importlib
def import_submodules(module):
files = glob.glob(os.path.join(os.path.dirname(module.__file__), '[a-zA-Z0-9]*.py'))
names = [os.path.split(os.path.splitext(file)[0])[1] for file in files]
submodules = [importlib.import_module('.'.join([module.__name__, name])) for name in names]
return submodules