Pythonでimportの対象ディレクトリのパスを確認・追加(sys.pathなど)
Pythonのimport
文で標準ライブラリやpipでインストールしたパッケージ、自作のパッケージなどをインポートするときに探索されるパス(ディレクトリ)をモジュール検索パス(Module Search Path)と呼ぶ。
自作のパッケージやモジュールをインポートしたい場合は正しく設定しておく必要がある。
ここではimport
の対象となるディレクトリのパスであるモジュール検索パスを確認したり新たに追加したりする方法を説明する。
import
の基本的な使い方などは以下の記事を参照。
sys.pathでモジュール検索パスを確認
モジュール検索パスは標準ライブラリのsys
モジュールのsys.path
に格納されている。
sys.path
はディレクトリのパスを文字列として格納したリストオブジェクトなのでprint()
で中身を確認できる。
ここではpprint
を使って見やすくしている。
import sys
import pprint
pprint.pprint(sys.path)
これを実行すると以下のような結果が得られる。
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
python3 print_sys_path.py
# ['/Users/mbp/Documents/my-project/python-snippets/notebook',
# '/Users/mbp/Documents/lib',
# '/Users/mbp/Documents/my-project/python-snippets/notebook',
# '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python37.zip',
# '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
# '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload',
# '/usr/local/lib/python3.7/site-packages']
結果は環境によって異なるが、例の環境(HomebrewでPython3をインストールしたMac)では、
- スクリプトファイル(
.py
ファイル)があるディレクトリ - 環境変数
PYTHONPATH
で指定したディレクトリ(後述) - カレントディレクトリ
- 標準ライブラリのためのディレクトリ(3つ)
pip
でインストールしたサードパーティライブラリのためのsite-packages
ディレクトリ
が格納されている。
ターミナルでカレントディレクトリを移動して再度実行すると、3. カレントディレクトリ
が変化していることが分かる。
cd ..
pwd
# /Users/mbp/Documents/my-project/python-snippets
python3 notebook/print_sys_path.py
# ['/Users/mbp/Documents/my-project/python-snippets/notebook',
# '/Users/mbp/Documents/lib',
# '/Users/mbp/Documents/my-project/python-snippets',
# '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python37.zip',
# '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
# '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload',
# '/usr/local/lib/python3.7/site-packages']
スクリプトファイルを実行する場所によってインポートがうまくいったりいかなかったりするのは、カレントディレクトリによってモジュール探索パスが変わっているのが原因。
また、sys.path
の先頭から優先してモジュールを探索するため、標準ライブラリと同じ名前のファイルがスクリプトファイルと同じディレクトリにあるとそちらがインポートされる。インポートはされているのに想定の関数などが使えない場合はこれが原因。該当ファイルをリネームするか移動すればよい。
sys.pathにモジュール検索パスを追加
sys.path
はただのリストなので、append()
メソッドなどで新たなパスを追加できる。
sys.path
にパスを追加したあとでimport
を行うと、追加したパスの中のモジュールがインポートできる。
例えばスクリプトファイルの一階層上のディレクトリを追加する場合は以下のように書ける。
import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
詳細は以下の記事を参照。
sys.path
への追加が有効なのはそのコードの中だけ。恒久的に特定のパスを追加したい場合は次に説明するPYTHONPATH
か.pth
ファイルを使う。
環境変数PYTHONPATHでモジュール検索パスを追加
恒久的にモジュール探索パスを追加する場合は、環境変数PYTHONPATH
を使う。
自作のライブラリを標準ライブラリやpipでインストールしたサードパーティライブラリのように使いまわしたい場合は、自作ライブラリをまとめて格納するディレクトリを作って、そのディレクトリのパスを環境変数PYTHONPATH
に設定する。
Macを含むUnix系OSの場合は、例えば~/.bashrc
などに以下のように追記する。複数パスを指定する場合コロン:
で区切る。
export PYTHONPATH="/path/to/add:$PYTHONPATH"
Windowsの場合も通常の環境変数と同様に「PC(マイコンピュータ)を右クリック→「システム」→「システムのプロパティ」→「環境変数」からPYTHONPATH
を新たに追加して設定すればOK。Windowsの場合は複数パスを指定する場合セミコロン;
で区切る。
自作のライブラリをPYTHONPATH
に追加したディレクトリに入れておけばsys.path
を処理することなくいつでもインポートして使えるようになるので便利。
上の例の'/Users/mbp/Documents/lib'
というディレクトリはPYTHONPATH
に追加したもの。
パス設定ファイル(.pth)でモジュール検索パスを追加
site-packages
ディレクトリの中にパス設定ファイル(.pth
)を置いておくと、その中身のパスもモジュール探索パスとして追加される。
パス設定ファイル(.pth
)には1行に1つのパスを記述する。相対パスでも絶対パスでもOK。#
でコメントを書くことも可能。拡張子がpth
であればファイル名は何でもよい。