Python を書いていると、import
の仕組みに悩んだことはありませんか?
特に 相対インポート は、パッケージ内のファイル同士で使うと便利ですが、初心者には少し分かりにくい部分もあります。
そこで今回は、実際に手を動かして 相対インポートの仕組み を理解していきましょう!🚀
1. ハンズオンの準備
まずは、次のような ディレクトリ構成 を作ります。
project/
│── main.py
│── package/
│ ├── __init__.py
│ ├── module_a.py
│ ├── module_b.py
│ └── subpackage/
│ ├── __init__.py
│ ├── module_c.py
│ └── module_d.py
各ファイルの役割
main.py
… プログラムの実行ファイルpackage/
… パッケージ(この中のファイルで相対インポートを試す)package/module_a.py
… 関数func_a()
を定義package/module_b.py
…module_a.py
から関数をインポートpackage/subpackage/module_c.py
… 関数func_c()
を定義package/subpackage/module_d.py
…module_c.py
から関数をインポート
では、それぞれのファイルの中身を見ていきましょう!
2. 各ファイルの中身
① module_a.py
(関数の定義)
def func_a():
return "Hello from module_a!"
② module_b.py
(相対インポートを使う)
from .module_a import func_a # 相対インポート
def func_b():
return f"func_b calls: {func_a()}"
③ module_c.py
(関数の定義)
def func_c():
return "Hello from module_c!"
④ module_d.py
(相対インポートを使う)
from ..module_a import func_a # 1つ上のディレクトリからインポート
from .module_c import func_c # 同じパッケージ内からインポート
def func_d():
return f"func_d calls: {func_a()} and {func_c()}"
⑤ main.py
(実行ファイル)
from package.module_b import func_b
from package.subpackage.module_d import func_d
print(func_b()) # module_b → module_a をインポート
print(func_d()) # module_d → module_c, module_a をインポート
3. 相対インポートの仕組み
Python の 相対インポート では、.
や ..
を使って、現在のディレクトリや上のディレクトリを指定できます。
from .module_a import func_a
の意味
from .module_a import func_a
.
は 現在のパッケージ(package/) を指すmodule_a.py
は 同じディレクトリ内 にあるので.
でインポートできる
from ..module_a import func_a
の意味
from ..module_a import func_a
..
は 1つ上のディレクトリ(package/) を指すmodule_a.py
は package/ の直下 にあるので..
を使ってアクセス
4. 実行結果
ターミナルで main.py
を実行してみましょう。
func_b calls: Hello from module_a!
func_d calls: Hello from module_a! and Hello from module_c!
✅ 相対インポートが正しく動作しました!
5. まとめ
✅ 絶対インポート の場合
from package.module_a import func_a
✅ 相対インポート の場合
- 同じパッケージ内 なら
from .module_a import func_a
- 1つ上のディレクトリ なら
from ..module_a import func_a
相対インポートのメリット
✅ シンプルな記述でモジュールをインポートできる
✅ パッケージの構造が変わっても、修正が少なくて済む
Python のパッケージを整理するときには、ぜひ 相対インポート を活用してみてください!💡