0
1

【Python】importの相対パスを解決

Posted at

はじめに

Python で以下のようなディレクトリ構造のとき, app/hoge.py と test/fuga.py 間で相対パスを使いたい時の備忘録です.

ディレクトリ構造

root
├── app
│   └── hoge.py
└── test
    ├── __init__.py
    └── fuga.py

結論

以下の手順で,hoge.py から fuga.py のクラスをインポートして使用することができます.

ソースコード

hoge.py
import sys
sys.path.append('../')
from test import Fuga

def main():
    Fuga.greeding()

if __name__ == "__main__":
    main()
__init__.py
from .fuga import *
fuga.py
class Fuga:
    @staticmethod
    def greeding():
        print("Hello from Fuga!")

コマンド

$ cd ./app
$ python3 hoge.py 

事前知識

相対パス
相対パスは,カレントディレクトリを.,現在の階層から1つ上の階層を..で表記することができます.app がカレントディレクトリの場合,fuga.py は ../test/fuga.py と表せます.

__init__.py
__init__.py をディレクトリ内に作成すると,そのディレクトリがパッケージとして認識されます.

sys.path.append
sys.pathは、Pythonがモジュールやパッケージを検索する際に使用するディレクトリのリストです。Pythonはimport文を実行するとき、このリストに含まれるディレクトリを順番に検索し、最初に見つかったモジュールをインポートします。つまり親ディレクトリへのpathはsys.pathにないためエラーになります.(次項参照)

注意

Pythonのimport文では,hoge.py から fuga.py を呼び出そうとした時 from ..test import Fuga のように表記したくなりますが,ImportError: attempted relative import with no known parent package エラーが発生します.
これは,スクリプトを直接実行する場合,Pythonがそのスクリプトの親パッケージを認識しないためです.
Pythonはセキュリティの問題で,認識しないようにしているそう...

この問題を回避するために,sys.path を使って親ディレクトリ(ここでいうroot)を追加します.それにより,子ディレクトリ(ここでいう/app)から親を認識できるようにします.

詳細説明

hoge.py
sys.path.append('../') を使って親ディレクトリをパスに追加することで,test パッケージをインポートできるようにします.
rootディレクトリからは/test, /appが見えるためインポートできるようになります.
その後,from test import Fuga で fuga.py からクラスをインポートします.

from ディレクトリ名 import クラス名に注意してください.
ファイル名(fuga)とクラス名(Fuga)の間違いで悩んでたことがあります.

__init__.py
このファイルは,test ディレクトリをパッケージとして認識させるために必要です.
__init__.py ファイル内で fuga.py をインポートします.

fuga.py
クラス Fuga を定義します.このクラスには,greeding という静的メソッドが含まれており,"Hello from Fuga!" と出力します.

実行方法

app ディレクトリに移動して hoge.py を実行します.これにより,hoge.py が親ディレクトリ .. をパスに追加し,test パッケージから Fuga クラスを正しくインポートできるようになります.

$ cd ./app
$ python3 hoge.py 

実行結果

Hello from Fuga!

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1