Python の 検索パスと import
検索順
- 実行時のカレントディレクトリ
- 実行中スクリプトのあるディレクトリ (パッケージ実行時)
- PYTHONPATH 環境変数で指定されたディレクトリ
- Python 標準ライブラリのディレクトリ
- インストールされた 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
)を通して外からも使えるようにするから