Python の相対インポートをハンズオンで解説!5.7

当サイトではアフィリエイト広告を利用しています。

リファレンス

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.pymodule_a.py から関数をインポート
  • package/subpackage/module_c.py … 関数 func_c() を定義
  • package/subpackage/module_d.pymodule_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.pypackage/ の直下 にあるので .. を使ってアクセス

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 のパッケージを整理するときには、ぜひ 相対インポート を活用してみてください!💡