LoginSignup
36

More than 5 years have passed since last update.

[Python] ModuleNotFoundError解決方法

Last updated at Posted at 2019-01-05

Pythonで別ディレクトリのモジュールをインポートしようとすると、ImportErrorModuleNotFoundErrorが吐き出されることがあります。
このエラーはインポートしようとしたモジュールが、検索対象のパス(sys.path)の中に含まれていないことが原因です。
これを解決する方法を3つ書きます。

デモ環境

ディレクトリ構造は以下のように想定し、app/app.pyからlib/module.pyを読み込もうと思います。

$ pwd
/home/test/

$ tree
.
├── app
│   └── app.py
└── lib
    └── module.py

sys.path.append()

app/app.pyでsys.path.append()でsys.pathに任意のディレクトリを追加して、そのディレクトリをモジュール探索対象にします。

app.py
import sys
sys.path.append('../lib')
from module import hello

hello()

しかし、この方法はPythonのコーディング規約であるPEP8に違反しています。

$ pycodestyle app/app.py 
app/app.py:3:1: E402 module level import not at top of file

出力されたメッセージによると、モジュールをインポートするためのコードはファイルの上部になければならない、ということらしいです。
別のディレクトリにあるモジュールをインポートする前にsys.path.append('../lib')を実行しているのが原因です。
PEP8に準拠したい場合はこの方法は推奨しません。⬅というか、PEP8に準拠すべきです。

PYTHONPATH

PYTHONPATHという環境変数に自作モジュールのフルパスを代入します。

export PYTHONPATH="$PYTHONPATH:/home/test/lib"

これでsys.pathに追加されます。
しかし、一時的にsys.pathに追加されているだけなので、シェルの別タブや新規シェルではsys.pathには含まれません。
永続的に有効にしたい場合は次のようにします。

echo 'export PYTHONPATH="$PYTHONPATH:/home/test/lib"' >> ~/.bashrc

拡張子pthファイル

拡張子がpthであるファイルをsys.pathに含まれているディレクトリ下に置きます。ファイルの名前は任意です。
ファイルの中には自作モジュールのフルパスを一行に一つ書きます。

デモ環境では、sys.pathに~/.local/lib/python3.6/site-packagesが含まれていると仮定します。

echo "/home/test/lib" > ~/.local/lib/python3.6/site-packages/mymodules.pth

これだけで、ファイルに書いたパスがsys.pathに追加されます。
ちなみに、拡張子pthでは#でコメントアウトできます。

3つの解決方法を書きましたが、管理のしやすさから拡張子pthのファイルを使用する方法が、個人的にはいいと思っています。

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36