__init__.pyの__all__
__all__ の使用方法を説明するために、簡単な例を挙げてみましょう。想定するパッケージ構造は以下の通りです:
my_package/ __init__.py
module_a.py
module_b.py
ここで、module_a.py と module_b.py があるとします。
module_a.py
# module_a.py
def public_function():
print("これは公開関数です。")
def _private_function():
print("これは非公開関数です。")
module_b.py(__all__ を使用)
# module_b.py
__all__ = ["public_function_b"]
def public_function_b():
print("これはmodule_bの公開関数です。")
def _private_function_b():
print("これはmodule_bの非公開関数です。")
__init__.py
# __init__.py
from .module_a import *
from .module_b import *
module_b.py で __all__ を定義しているため、from my_package import * を実行すると、module_b の public_function_b のみがインポートされます。一方で、module_a.py では __all__ を定義していないため、public_function と _private_function が両方ともインポートの対象となりますが、通常、アンダースコア (_) で始まる関数や変数は非公開(プライベート)として扱われ、外部からのインポートを意図していないことが多いです。
以下のように、my_package を使用する外部スクリプトからインポートを試みると、この挙動が確認できます。
# 外部スクリプト
from my_package import *
public_function() # module_aのpublic_functionが呼び出される
public_function_b() # module_bのpublic_function_bが呼び出される
_private_function や _private_function_b は、__all__ の定義によってフィルタリングされているため(または慣習によって非公開とみなされているため)、この方法ではインポートされません。
この例からわかるように、__all__ を使うことでモジュールやパッケージから公開されるシンボルを明示的に制御でき、外部からアクセス可能なAPIの範囲を定義するのに役立ちます。これにより、内部実装の詳細を隠蔽しつつ、必要な機能のみを提供することが可能になります。
この記事が気に入ったらサポートをしてみませんか?