Skip to main content

Python の 検索パスと import

検索順

  1. 実行時のカレントディレクトリ
  2. 実行中スクリプトのあるディレクトリ (パッケージ実行時)
  3. PYTHONPATH 環境変数で指定されたディレクトリ
  4. Python 標準ライブラリのディレクトリ
  5. インストールされた site-packages など

何を探しに行くか

py
from sugoi_utils import sugoi_func

とした場合、検索パスから sugoi_utils.py を探しに行く

「実行中スクリプトのあるディレクトリ」について

  • sugoi_utils.py を直接使っていたスクリプトの隣に置いていれば、カレントが違ってもインポートできる
  • これは Python がそのファイルの場所を自動で含めてくれるため
  • ただしこれは直接スクリプトとして実行する場合に限る

スクリプト内で明示的にパスを追加する場合

例えばこうやって、スクリプトのあるディレクトリを起点に、絶対パスを取得して、明示する

py
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

import する側、される側

別ファイルに出した関数 (import される側)

sugoi_utils.py

SUGOI_CONSTANT1 = 999

def sugoi_func1():
print('hi!')

ポイント

  • import 時の名前(モジュール名)について
    • ファイル名に明示するだけ
    • クラス名のようにファイル内に書く訳ではない
  • 定義したものはファイル内スコープ
    • import しない限り、外から参照はできない
    • なので、定数を定義したところで、グローバルは汚れない
  • shebang は要らない

呼びもと (importする側)

関数/定数指定で import する場合

py
#!/usr/bin/env python3

from sugoi_module1 import SUGOI_CONSTANT1
from sugoi_module1 import sugoi_func1

print(SUGOI_CONSTANT1)

sugoi_func1()

モジュール指定で import する場合

呼び出しが冗長かもしれないが、こっちのほうが分かりやすいと思う。

py
#!/usr/bin/env python3

import sugoi_module1

print(sugoi_module1.SUGOI_CONSTANT1)

sugoi_module1.sugoi_func1()

import sugoi_module1 as sm1 などと別名にした場合は
sm1.sugoi_func1() のように呼べる。
ただ、可読性を考えると、あまり特殊な短縮名にはしないのが良いと思う。

用語の整理

  • ファイルに出しているのが「モジュール」
  • ディレクトリ(__init__.pyを含むもの)に出しているのが「パッケージ」
  • パッケージ内の py ファイルが「サブモジュール」
py
# モジュールのimport
import sugoi_module1

# モジュール内の関数の import
from sugoi_module1 import sugoi_func1

# サブモジュール内の関数の import
from sugoi_package1.sugoi_submodule1 import sugoi_submodule_func1

# サブモジュール内の関数の import : __init__.py で import している場合 (これを再エクスポートと言う)
from sugoi_package1 import sugoi_submodule_func1
__init__.py
from .sugoi_submodule1 import sugoi_submodule_func1
  • Q1.
    • Q. 再エクスポートは、その関数が、どのモジュールのものか 一見分からなくなってしまう
    • A. ファイル管理上分けたいが、使う側からは どのモジュールかを区別する必要がないとき、といった使い方をするのでしょう
  • Q2.
    • Q. なんで import しているのに「再エクスポート」と言うのか
    • A. import して、自分(パッケージの __init__.py)を通して外からも使えるようにするから