【python】自作モジュールをimportするとModuleNotFoundErrorが出てしまう

【python】自作モジュールをimportするとModuleNotFoundErrorが出てしまう

 自作モジュール作成に慣れてくると、フォルダ構成を階層化して管理したくなってきます。その時に発生するModuleNotFoundErrorを回避する方法を記載します。
 複数のフォルダにまたがって自作モジュールがある場合はフォルダ指定を自動化しておくと便利です。
【python】自作モジュールをimportするとModuleNotFoundErrorが出てしまう_フォルダ階層が複雑 │ プログラミングのメモ帳 (sun-sun-sunday.com)

はじめに

 イメージがつかみにくい方は下記サンプルプログラムをダウンロードください。(zipから解凍してフォルダ構成を変えずにmain.pyを実行ください。)

フォルダ構成

test(フォルダ)
|main.py
|-under(フォルダ)
|-sample1.py
|-under2(フォルダ)
|-sample0.py

 sample1.pyとsample0.pyは親子関係で、sample1はsample0の関数を呼びに行くことでプログラム実行されます。

【sample1.py】

def hyouji():
    from under2 import sample0

    print("sample1")
    sample0.hyouji()

if __name__ == '__main__':
    test=hyouji()

【sample0.py】

def hyouji():

    print("sample0")

if __name__ == '__main__':
    test=hyouji()

sample1.py実行結果

想定通りにサンプル0とサンプル1が表示されます。
これで自作モジュールの準備ができたので呼び込み元のmainプログラムをつくって読み込みましょう!

main.pyを作ってsample1を読み込もう!

 タイトルの通りなのですが単純にimportするとModuleNotFoundErrorがでます。(正確にはフォルダ構成次第ですが、ここまでの思考が筆者と近ければ同じエラーにたどり着きます)下記コードを実行してみるとエラーが出ます。コメントアウトにほぼ答えがあるのは気にしないでください(ぇ

【main.py】(仮)

#import sys
#from os import path
#m_path = path.join(path.dirname(__file__),"under")
#sys.path.append(m_path)

from under import sample1

sample1.hyouji()

 ちゃんとsample1.pyのるフォルダを指定しているのにsample1.pyを直接実行したときと同じ結果が得られません。

エラー回避方法

【main.py】

import sys
from os import path
m_path = path.join(path.dirname(__file__),"under")
sys.path.append(m_path)

import sample1

sample1.hyouji()

 sys.path.appendを使って自作モジュールのフォルダを指定してください。これで動きます。

あとがき

 自作モジュールをどんどん作っていくとフォルダ階層を分けたりして整理したくなってくると思います。筆者は「やった!これでプログラム作るの簡単になるぞ!」と喜んだのですが単体のモジュールで動くのになぜかimportするとエラーが発生する・・・。なんで!!!!????という疑問を乗り越えられずに数日時間を浪費したのはいい思い出です・・・。