はじめに
普段はC++を使っているのですが,Pythonで何気なくプログラミングをしていて,ソースコードが長くなることを避けるために関数のファイルを分割してimport
をしようと思いました.
同じことで困る人もいると思ったので,素早く解決できることを願います.短気な方はこちらへジャンプしてください.
他のコードからもimport
することを見越して,
$ tree
.
├── dir1
│ ├── mod1.py
│ ├── mod2.py
│ └── mod3.py
└── dir2
└── main.py
のようなフォルダ構造でやろうと思っていました.
また,書くときに面倒にならないように,dir1.mod1.func1()
のようではなく,func1()
と関数を使用できるようにしたかった.
問題
from ..dir1 import mod1
print('import was completed!')
のようにすると,
$ python main.py
Traceback (most recent call last):
File "main.py", line 1, in <module>
from ..dir1 import mod1
ValueError: attempted relative import beyond top-level package
と怒られてしまった.ディレクトリに入れてないのかな
と思い,mod1.py
を一つ上の階層に移して
from .. import mod1
print('import was complated!')
と変更した結果,
$ python main.py
Traceback (most recent call last):
File "main.py", line 1, in <module>
from .. import mod1
ValueError: attempted relative import beyond top-level package
また怒られた.
解決方法
調べてみると,
実行ディレクトリをルートとする
という仕様があるらしく,上のディレクトリにいけないらしい.
そこで,
import sys
sys.path.append('../')
from dir1.mod1 import *
if __name__ == '__main__':
importTest()
def importTest():
print('import was completed!')
と変更して実行すると,
$ python main.py
import was completed!
できた.
改善
このままでは,dir1/
内のmod1.py
,mod2.py,
mod3.py全てを
import`する場合,3行要してしまうのは嬉しくなく,
$ tree
.
├── dir1
│ ├── __init__.py
│ ├── mod1.py
│ ├── mod2.py
│ └── mod3.py
└── dir2
└── main.py
のようにした.各ファイルの中身は以下のようにした.この書き方をすることで,関数をそのまま使うことができた.
import sys
sys.path.append('../')
from dir1 import *
if __name__ == '__main__':
importTest1()
importTest2()
importTest3()
from .mod1 import *
from .mod2 import *
from .mod3 import *
def importTest1():
print('mod1 import was complated!')
def importTest2():
print('mod2 import was complated!')
def importTest3():
print('mod3 import was complated!')
この実行結果は
$ python main.py
mod1 import was complated!
mod2 import was complated!
mod3 import was complated!
これで当初の目的が果たされた.
Gitで使う際
以上のものを使用する際には__pycache__
が邪魔だったため,.gitignore
へ以下を追記.
*__pycache__/
参考
-
https://chaika.hatenablog.com/entry/2018/08/24/090000
- 上の階層のPATHを追加
-
https://note.nkmk.me/python-relative-import/
- 別ディレクトリからの
import
の仕方
- 別ディレクトリからの
-
https://qiita.com/karadaharu/items/37403e6e82ae4417d1b3
- ディレクトリ丸々
import
- ディレクトリ丸々
おわりに
一応希望通りの動きは果たせたのですが,応急処置感が否めないので,もっといいやり方があったら教えていただけると幸いです.