Pythonでモジュールやパッケージを使う際に、インポート方法やパス指定などで混乱することがあったので、自分の学習メモとして整理しました。
用語の整理
用語 | 説明 |
---|---|
モジュール |
.py ファイル1つ。関数やクラスなどを定義する |
パッケージ | モジュールをまとめたフォルダ。__init__.py を含む |
サブモジュール | パッケージ内にある .py ファイル |
__init__.py |
パッケージ初期化ファイル。空でも良いがインポート制御にも使える |
__all__ |
from package import * のときに読み込むモジュール名リストを定義する |
インポートの基本
モジュールから関数を使う
# math_utils.py に定義された関数を使う
from math_utils import add
add(1, 2)
パッケージからモジュールを使う
from my_package import a
a.func_a()
モジュール内の関数を直接使う
from my_package.a import func_a
func_a()
import * の動作と __all__
モジュールの場合(.py
ファイル)
from math_utils import *
add(1, 2) # OK
パッケージの場合(フォルダ)
from my_package import *
a.func_a() # ❌ エラー(__init__.py に __all__ がないと使えない)
__init__.py
に以下を記述:
__all__ = ['a', 'b']
これで以下のようにアクセスできる:
from my_package import *
a.func_a() # OK
関数を直接インポートしたい場合の __init__.py
from .a import func_a
__all__ = ['func_a']
from my_package import *
func_a() # OK
__init__.py
とは?
- パッケージであることを示すファイル
- 空でも構わない(Python 3.3以降はなくてもパッケージとして扱われる)
- モジュールのインポートをまとめたり、初期化処理を書いたりできる
-
__all__
もここに記述する
例:
# __init__.py
from .a import func_a
from .b import func_b
__all__ = ['func_a', 'func_b']
パスの考え方(絶対パスと相対パス)
絶対パス(絶対インポート)
プロジェクトのルートディレクトリからのフルパス指定。
from my_package.a import func_a
明確で可読性も高く、大規模プロジェクトではこちらが推奨されることが多いです。
相対パス(相対インポート)
現在のファイルの位置から相対的に指定する方法です。
from . import a # 同じパッケージ内の a.py をインポート
from .a import func_a # a.py 内の関数を直接インポート
from .. import shared_utils # 1階層上のモジュールをインポート
注意点として、相対パスは「スクリプトを直接実行する場合」は動かないことがあります。
その場合は、以下のように -m
オプションでパッケージとして実行する必要があります。
python -m my_package.main
推奨スタイルまとめ
書き方 | 説明 | 推奨度 |
---|---|---|
from module import * |
モジュールの全てをインポート。衝突の恐れあり | ❌ 非推奨 |
from module import name |
必要なものだけ明示的にインポート | ✅ 推奨 |
from package import module |
パッケージ構造を保ちながら使える | ✅ 推奨 |
相対インポート | パッケージ内で使いやすいが注意点あり | ◯ 条件付きで有効 |
まとめ
モジュールやパッケージの違い、インポートの種類、パス指定の違いを整理して理解が深まりました。
特に from xxx import *
の動作の違いや __init__.py
の使い方、相対パスと絶対パスの使い分けは、実際に試してみることで理解しやすくなると感じました。