自作のpythonのパッケージにおいて、その内部のモジュール単位での実行と、外部のスクリプトからのパッケージの利用の両方でうまく動作するimport
の書き方が知りたいです。
環境
- Windows10
- python3.7.0
- ファイル構成は以下の通り
main.py my_package/ __init__.py mod.py submod.py
以下でそれぞれのファイルについて説明します。
init.py
何も記載していません。
submod.py
submod.pyはsubfnc
の実装があります。
py
1def subfnc(): 2 print("subfnc called")
mod.py
mod.pyはsubmod.pyを使って処理をします。
py
1from submod import subfnc 2 3def fnc(): 4 print("fnc called") 5 subfnc() 6 7# 単体テスト用 8if __name__ == "__main__": 9 print("do something to test fnc()")
ここでpython .\my_package\mod.py
を実行すると単体テストが実行できます。タイトルの"モジュールのスクリプト動作"とはここを指しています。ここまではOKです。
main.py
main.pyは以下のようにmy_package内のmodをimport
して使います。
py
1from my_package.mod import fnc 2 3fnc()
これがmy_packageのパッケージとしての本来の使い方(ここがタイトルの"パッケージ外からの利用")かと思います。ただしpython .\main.py
を実行すると以下のようなエラーが発生します。
ModuleNotFoundError: No module named 'submod'
試したこと
ネットで調べると、python3.3以降では相対パスの明示化が必要とのことなので、mod.pyのimport
部分に.
を追加しました(下記)。
py
1# "."を追加して".submod"とした 2from .submod import subfnc 3 4def fnc(): 5 print("fnc called") 6 subfnc()
この場合はエラーが発生していたコマンドpython .\main.py
がうまくいきました。ただし今度は単体テストのpython .\my_package\mod.py
でエラーが発生するようになりました。
ModuleNotFoundError: No module named 'main.submod'; 'main' is not a package
調査するとモジュールをスクリプトとして実行するときは-m
をつけろという情報もあったので、python -m .\my_package\mod.py
としましたが、今度は違うエラーとなりました。
Relative module names not supported
そのほかにもsys.path.append()
しろ、とか出てきますが、なんだかややこしすぎてもっと簡潔な方法がないものかと思い、この辺りのノウハウなどを教えていただきたいです。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/01/14 14:46