note.nkmk.me

Pythonでimportの対象ディレクトリのパスを確認・追加(sys.pathなど)

Date: 2018-07-22 / tags: Python

Pythonのimport文で標準ライブラリやpipでインストールしたパッケージ、自作のパッケージなどをインポートするときに探索されるパス(ディレクトリ)をモジュール検索パス(Module Search Path)と呼ぶ。

自作のパッケージやモジュールをインポートしたい場合は正しく設定しておく必要がある。

ここではimportの対象となるディレクトリのパスであるモジュール検索パスを確認したり新たに追加したりする方法を説明する。

  • sys.pathでモジュール検索パスを確認
  • sys.pathにモジュール検索パスを追加
  • 環境変数PYTHONPATHでモジュール検索パスを追加
  • パス設定ファイル(.pth)でモジュール検索パスを追加

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)では、

  1. スクリプトファイルがあるディレクトリ
  2. 環境変数PYTHONPATHで指定したディレクトリ(後述)
  3. カレントディレクトリ
  4. 標準ライブラリのためのディレクトリ(3つ)
  5. 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の先頭から優先してモジュールを探索するため、標準ライブラリと同じ名前のファイルがスクリプトファイルと同じディレクトリにあるとそちらがインポートされる。インポートはされているのに想定の関数などが使えない場合はこれが原因。該当ファイルをリネームすればOK。

sys.pathにモジュール検索パスを追加

sys.pathはただのリストオブジェクトなので、append()メソッドなどで新たなパスを追加することが可能。

sys.pathにパスを追加したあとでimportを行うと、追加したパスの中のモジュールがインポートできる。

例えばスクリプトファイルの一階層上のディレクトリを追加する場合は以下のように書ける。

import os
import sys

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

from my_package import mod1

詳細は以下の記事を参照。

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であればファイル名は何でもよい。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事