【エラー対処】PyCharmでモジュール読み込みエラーが発生する


はじめに

PyCharm便利ですよね
VSCodeだと色々と設定がいりますが、IntelliJは大体の設定をいい感じに使用しているので、普段使いしやすいないようになっています。

最近PyCharmで開発をしているとPythonのモジュール読み込みエラーが発生するため、それの解決方法をまとめます。

ファイル構成

今いるフォルダがpython_how_to_moduleというフォルダで、このフォルダに対して「プロジェクトを開く」をしています。
その中のディレクトリ構成は以下です。

.
├── README.md
└── calc
    ├── __pycache__
    │   ├── add.cpython-36.pyc
    │   └── add.cpython-37.pyc
    ├── add.py
    └── print.py

画像で貼ると以下のようになります。

問題

モジュール化・パッケージ化を学ぶためにこのpython_how_to_moduleを作り
calcというフォルダを作って、その中にadd.pyとprint.pyを作りました。

add.pyは以下のようにします。

def add(x, y):
    return x + y


if __name__ == "__main__":
    print(add(10, 20))

上記のファイルをprint.pyから呼び出して、add.pyをモジュールとして利用するわけです。

そこで、PyCharmの表記上エラーが出ないようにprint.pyを書くと以下のようになりました。

from . import add

print(add.add(2,3))

これはおかしいですね・・・。
モジュール化なら、別にカレントディレクトリを示す「.」などはいらないはずです。
通常なら

import add

print(add.add(2,3))

のようになるはずです。

この


from . import add

では、PyCharmの表記上はエラーが出ません。

しかし、Control+Rで実行すると以下のようなエラーが発生します。

/Users/ganariya/.pyenv/versions/3.7.3/bin/python /Users/ganariya/Desktop/python_how_to_module/calc/print.py
Traceback (most recent call last):
  File "/Users/ganariya/Desktop/python_how_to_module/calc/print.py", line 1, in <module>
    from . import add
ImportError: cannot import name 'add' from '__main__' (/Users/ganariya/Desktop/python_how_to_module/calc/print.py)


次に、通常通り、普通ならうまく動くはずのファイルの書き方をしてみます。

import add

print(add.add(2,3))

上記はPyCharm上では赤線、つまりエラー判定され、インテリセンスも効かなくなってしまいます。

ただ、PyCharm上ではエラー判定されますが、実行はうまく行きます。
どうやらPyCharmの問題のようです。

ソースルートの指定

このような問題が起こる原因はどうやら

  • PyCharmがデフォルトでフォルダを作成すると、パッケージであるとして判断する
  • ソースコードのすべてのルートがpython_how_to_moduleである、というのがデフォルトになっている。

というのが原因のようです。
そのため、PyCharmの表記エラーを防ぐためにはfrom .のようにカレントディレクトリ指定をする必要があり、実行時はエラーが出るようです(当然実行時はカレントディレクトリ指定がいらないため(モジュールであるため))

そこで、ソースルートを指定します。
今回使用したいフォルダcalcを右クリックしてソースルートを選択します。

以上の操作を行うことで通常の書き方

import add

print(add.add(2,3))

でエラーが出ず、なおかつインテリセンスが効くようになります。

最後に

PyCharm特有のエラーの解決方法についてまとめました。
しかし、問題の内容の原因理解には至っていません。
もし、分かる方がいらっしゃったら教えていただけるとありがたいです。

Pythonを雰囲気で使っているため、きちんと理解して使用していきたいと思います!