cannot import name の解決方法一覧
cannot import nameエラーが発生したら、まず疑うべきは循環参照(circular import)の発生です。Qiitaでcannot import nameを検索すると大体循環参照が出てきますし、大体循環参照が原因です。
その他考えられる原因は、
1 インポートするファイル名と、Pythonの標準ライブラリや既存のモジュール名が同じ場合
2 スペルミス
3 相対パスのミス
4 モジュールの定義の順序によって、インポートされる側のモジュールがまだ完全に初期化されていない場合
5 古いバージョンのPythonまたはライブラリを使用している
6 モジュールや関数が存在しない
くらいですかね。ほかにあったら教えてください。
今回詳しく説明するのは、別のフォルダのモジュールを参照しようとしてしまっているケースです。
別フォルダのモジュールを参照したいとき(本題)
まずなぜ他フォルダのモジュールを参照できないか
pythonは怠け者なので、通常、以下の場所でのみモジュールを探します。
・現在の作業ディレクトリ(実行中のスクリプトのディレクトリ)
・sys.pathにリストされているディレクトリ
・PYTHONPATH環境変数に指定されたディレクトリ
なので、野生のフォルダに含まれるファイル内のモジュールを自動で参照することはありません。
ではどうするか
色々方法があります。ただ手動でsys.pathに入れたり、現在の作業ディレクトリにわざわざファイルを新しく作ったりは面倒なので、簡単な方法だけを紹介します。ちなみにVSCodeを使ってるので、他だとまた変わるかもしれません。
1 ルートディレクトリに「.vscode」という名前のフォルダを作る。フォルダ内に「settings.json」ファイルを作る
「settings.json」ファイルの中身は↓
(FOLDERNAMEを参照したいコードの位置するフォルダの名前に変えてください)
{
"python.analysis.extraPaths": [
"./FOLDERNAME"
]
}
2 使いたいコードの頭に↓のコードを入れたら完成。(CLASS1を実際に使いたいクラス、関数名、変数等に置き換える。)
sys.path.append(r'FOLDERNAMEの絶対パス')
from FOLDERNAME import CLASS1
こうすることで、Test.py実行時にpythonはFOLDERNAME内も検索するようになって、エラーが解消されます。
まとめ
多分ほかにもいい方法があるのかもしれないし、VScode以外だとまた方法も違ってくると思うので、今後追加するかもしれません。