TL;DR
モジュールをインストールした後、ファイルに「import モジュール名」を記載すると ModuleNotFoundError というエラーが出る場合の対処法。
ModuleNotFoundError が出たときは、次の 3 点を確認する。
- モジュールが格納されているパスを確認する
- .bashrc に PYTHONPATH を記述する
- .bashrc を再読み込みする
ModuleNotFoundError
ModuleNotFoundError は、モジュールが読み込めていないことを表している。
インポートを試みたがモジュールが読み込めない、そういった場合に表示される。
例えば、MySQL へ接続するモジュール mysqlclient を インストールし、test.py というファイルの冒頭にインポート文を記述したとしよう。
import MySQLdb
しかし、いざ Python を走らせようとすると、次のようにモジュールの読み込みエラーがでる。
Traceback (most recent call last):
File "/Users/ユーザー名/projects/Python/test.py",
line 1, in <module>
import MySQLdb
ModuleNotFoundError: No module named 'MySQLdb'
こういうケースでは、モジュール名の見直しを行うか、.bashrc に モジュール検索パスである PYTHONPATH を指定してあげると解決することがある。
手順
モジュールが格納されているパスを確認する
次の方法でモジュールがインストールされているパスを調べる。pprint を使って、パスを整形表示したほうが見やすい。
>>> import sys
>>> import pprint
>>> pprint.pprint(sys.path)
['',
'/Users/ユーザー名/.pyenv/versions/3.9.6/lib/python39.zip',
'/Users/ユーザー名/.pyenv/versions/3.9.6/lib/python3.9',
'/Users/ユーザー名/.pyenv/versions/3.9.6/lib/python3.9/lib-dynload',
'/Users/ユーザー名/.pyenv/versions/3.9.6
/lib/python3.9/site-packages']
上記の場合、パスは通っている。モジュールは「site-packages」以下に格納されている。
パスが通ってない場合は、モジュールが格納されている場所を探し、ディレクトリを直接確認してみよう。
ユーザー
└── .pyenv
└── versions
└── 3.9.6
└── lib
└── python3.9
└── site-packages
├── MySQLdb
├── numpy
├── path
└── pip
そして、パスを追加する。
>>> sys.path.append('パス')
.bashrc に PYTHONPATH を記述する
.bashrc に、先程調べたモジュールのパスを追加する。.bashrc の場所は、Mac の場合 /Users/ユーザー名/
の中にある。
PYTHONPATH の記述方法はこちらである。PYTHONPATH は、モジュールファイルのデフォルトの検索パスを追加する。
$ export PYTHONPATH="モジュールへのパス:${PYTHONPATH}"
ディレクトリパスの最後にはスラッシュは付けない。
$ export PYTHONPATH="/Users/ユーザー名/.pyenv/versions/3.9.6/lib/python3.9/site-packages:${PYTHONPATH}"
この環境変数のフォーマットは、(Unix ならコロン、 Windows ならセミコロン) で区切られた 1 つ以上のディレクトリパスです。存在しないディレクトリは警告なしに無視されます。 コマンドラインと環境 — Python 3.10.0b2 ドキュメント
.bashrc を再読み込み
保存したら、忘れずに.bashrc を再読み込みする。
$ source ~/.bashrc
私の場合はこれで無事に稼働した。
上述した方法でも動かない場合
何かの理由で .bashrc を編集できない場合、次のように、py ファイルの上部に sys.path.addend()メソッドを直接記述することで動く可能性がある。
import sys
sys.path.append("/Users/ユーザー名/.pyenv/versions/3.9.6/lib/python3.9/site-packages")
import numpy as np