読者です 読者をやめる 読者になる 読者になる

DRYな備忘録

Don't Repeat Yourself.

Python3のimport・下位/上位階層のモジュールをインポートしたい【import】【Python3】

  • 基本的なPythonの自作モジュールimport
  • 浅いmain.pyから深い自作モジュールをimport
  • 深いmain.pyから上位階層にあるモジュールをimport

基本的なPythonの自作モジュールimport

メインで実行するファイルよりも同階層かpython_packageで管理されているモジュールのimportはだいたいこうやるっぽいすね

[20:13:03] % python --version
Python 3.3.2
[20:13:04] % tree
.
|-- main.py
`-- some_module.py

0 directories, 2 files

some_module.py

def some_method(some_arg):
  print(some_arg)

そしてmain.py

import some_module

some_module.some_method('Tainaka Ritsu')

これを実行すると(本論ではないですが、-Bをつけるとモジュールのキャッシュファイルである.pycがつくられないです)

[20:28:46] % python -B main.py
Tainaka Ritsu

main.pyから、同階層にあるモジュール"some_module"のメソッドを利用できてることを確認できました

浅いmain.pyから深い自作モジュールを呼ぶ

たとえばこんな感じで、深いところに自作モジュールつくった場合、実行するトップからどうやって呼ぶか

[20:44:45] % tree
.
|-- main_on_the_top.py
`-- mymodules
    |-- __init__.py
    `-- some
        |-- __init__.py
        `-- nested
            |-- __init__.py
            `-- mymodule.py

3 directories, 5 files

この場合、すべてのinit.pyは空ファイル(無言のファイル)で、main_on_the_top.pyは

from mymodules.some.nested import mymodule

mymodule.some_method('Tainaka Ritsu')

こうなります。実行

[20:46:32] % python -B main_on_the_top.py
Tainaka Ritsu

深いところにあるモジュールを利用できていることが分かります

深いmain.pyから上位階層にあるモジュールを呼ぶ

では、メインで実行するファイルがモジュールよりも下の階層にあった場合はどうするのか。たとえばこんな感じ

[21:04:21] % tree
.
|-- mymodule_on_the_top.py
`-- some
    `-- nested
        `-- main.py

2 directories, 2 files

some/nested/main.py

# cli tools for example...
import mymodule_on_the_top

mymodule_on_the_top.some_method()

実行しようとしても

[21:04:56] % python -B some/nested/main.py
Traceback (most recent call last):
  File "some/nested/main.py", line 3, in <module>
    import mymodule_on_the_top
ImportError: No module named 'mymodule_on_the_top'

というように叱られます

解決策

スクリプトを実行したカレントディレクトリをimportパスとして追加します

some/nested/main.py

# append import path
import os, sys
print(os.getcwd())
sys.path.append(os.getcwd())

import mymodule_on_the_top

mymodule_on_the_top.some_method('Tainaka Ritus')

これを実行すると

[21:30:39] % python -B some/nested/main.py
/home/otiai10/prj/python/test_project
Tainaka Ritus

print(os.getcwd())の出力が絶対パスの文字列なので、sys.path.appendにパスを書いた文字列渡せばどうにでもできる感ございますね。

参考

つかこれですやん > http://python.g.hatena.ne.jp/edvakf/20090424/1240521319

f:id:otiai10:20130813214909j:plain

暑い…

DRY