成果物
問題
下記ディレクトリ構成のとき、test.py
からmypackage.mymodule.mymethod()
を参照せよ。
src/ tests/ test.py mypackage/ mymodule.py def mymethod()
解法
- 実行するとき.pyのファイルパスは絶対パスにすること
$ python /tmp/Python.import.201709091150/src/tests/test.py
等
sys.path
(list型)に参照したいディレクトリの絶対パスを追加するコードを書く- その後
import mymodule
のようにimport文を書く
- その後
実行時のパスがtests/
だとエラーになる謎。
カレントディレクトリ | 実行コマンド | 結果 |
---|---|---|
/tmp |
$ python3 /tmp/Python.import.201709091150/src/tests/test.py |
OK! |
/tmp/Python.import.201709091150/src/tests/ |
$ python3 test.py |
ImportError: No module named 'mymodule' |
成功
$ python3 /tmp/Python.import.201709091150/src/tests/test.py /tmp/Python.import.201709091150/src/tests /tmp/Python.import.201709091150/src/mypackage /tmp/Python.import.201709091150/src/mypackage/__pycache__ mymodule mymethod
コード
test.py
#ひとつ上の階層における全ディレクトリをimportディレクトリに追加する import sys, os rootdir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) for root, dirs, files in os.walk(rootdir): for d in dirs: print(os.path.join(root, d)) sys.path.append(os.path.join(root, d)) import mymodule #import mypackage.mymodule mymodule.mymethod()
謎
test.pyのディレクトリからは同様に実行できないのが謎かつ面倒。わざわざ絶対パスを指定せねばならない苦痛。
ちなみに、importは以下のような記法もある。いまいち理解できていない。
import mymodule
from mypackage import mymodule
from . import mypackage.mymodule
$ python test.py -m src.mypackage.mymodule
解決できない問題
- モジュールまでの間にあるパッケージがすべて無視されてしまう
異なるパッケージに同一名のモジュールがあったとき、名前の衝突が起きると思われる。
所感
pythonのimportシステムは理解しづらく使いづらく見づらく書きにくく機能不足。自由なディレクトリ構成で自由に参照することができない。
という認識で正しいのかどうかもわからない。