Pythonのパスの書き方
pythonコマンドを使ってプログラムを実行した場合のインポートやファイル参照のパスについて、理解できていなかったので、実際に動かして動作を確認しました。
なお、相対パスはpythonコマンドで実行するモジュールでは使えないという制約があります。
fromの指定
ディレクトリ構造
ファイルの内容
main.py実行時
project_rootにて、python3 main.py
を実行する。
この時、child_module.pyのimport
文が以下だと、エラーになる。
次のようにchild_module.pyから見た相対パスまたは、main.pyから見たパスでgrandchild_module
を記載すると動作する。
結果
child_dir/sub_main.py実行時
次にproject_rootにて、python3 child_dir/sub_main.py
を実行する。
sub_main.pyのimport文
この時、sub_main.pyのimport
文が以下だと、エラーになる。
次のように、実行するモジュールからのパスだと正常に動作する。
child_module.pyのimport文
この時、child_module.pyのimport
文が以下だと、エラーになる。
次のように、実行するモジュールからのパスだと正常に動作する。
結果
sub_main.py実行時
次にchild_dirにて、python3 sub_main.py
を実行する。
この時の結果はproject_rootでpython3 child_dir/sub_main.py
実行時と同じだった。
結論
import
文はpythonコマンドで実行するモジュールからのパスで記載するか、import
されたファイルから見た相対パスを記載する。import
されたファイルと同一ディレクトリにあるモジュールの相対パスを記載時はfrom .パッケージ名 import モジュール名
となる。
pythonコマンドで実行するモジュールだけでなく、実行するモジュールと同じディレクトリにあるモジュールをimportした場合も、そのファイル内で相対パスは使えない。
ファイルパスの指定
ディレクトリ構造
main.py実行時
project_rootにて、python3 main.py
を実行する。
main.pyのfile_path
は以下のどちらでも正常に動作する。
この時、child_module.pyのfile_path
は以下だとエラーになる。
次のように、main.pyから見たパスだと正常に動作する。
grandchild_module.pyのfile_path
は以下だとエラーになる。
次のように、main.pyから見たパスだと正常に動作する。
child_dir/sub_main.py実行時
次にproject_rootにて、python3 child_dir/sub_main.py
を実行する。
この時、sub_main.pyのfile_path
が以下だと、エラーになる。
次のように、pythonコマンドを実行したディレクトリ(project_root)から見たパスだと正常に動作する。
同様にchild_module.pyのfile_path
もpythonコマンドを実行したディレクトリ(project_root)から見たパスだと正常に動作する。
grandchild_module.pyのfile_path
も以下だとエラーになる。
次のように、pythonコマンドを実行したディレクトリ(project_root)から見たパスだと正常に動作する。
sub_main.py実行時
次にchild_dirにて、python3 sub_main.py
を実行する。
この時、sub_main.pyのfile_path
が以下だと、エラーになる。
次のように、sub_main.pyから見たパスだと正常に動作する。
同様にchild_module.pyのfile_path
もpythonコマンドを実行したディレクトリ(child_dir)から見たパスだと正常に動作する。
grandchild_module.pyのfile_path
は以下だとエラーになる。
次のように、pythonコマンドを実行したディレクトリ(child_dir)から見たパスだと正常に動作する。
結論
FastAPI
ディレクトリ構成
ファイルの内容
project_root/main.pyでは、相対パスのimport
文だとエラーになる。
main.py実行時
project_rootにて、uvicorn main:app --host 0.0.0.0 --port 8000
を実行する。
この時、child_module.pyのimport
文が以下だと、エラーになる。
次のいずれかであれば、import
できる。(通常のpython実行時と同じ)
child_dir/sub_main.py実行時
次にproject_rootにて、uvicorn child_dir.sub_main:app --host 0.0.0.0 --port 8000
を実行する。
この時、sub_main.pyのimport
文が以下だと、エラーになる。
実行ディレクトリから見たパスまたは、実行ファイルから見た相対パスだとimport
できる。
import
されたファイルでは、実行ファイルから見たパスではimport
できない。また、import
されたファイルが、
- 実行ファイルと同じディレクトリの場合、実行ディレクトリからのパスで
import
文を記述できる - 実行ファイルのサブディレクトリの場合、実行ディレクトリからのパスまたは、対象ファイルからの相対パスで
import
文を記述できる
sub_main.py実行時
次にchild_dirにて、python3 sub_main.py
を実行する。
この時、sub_main.pyのimport
文が実行ファイルからの相対パスだと、エラーになる。
実行ディレクトリ(=実行ファイル)から見たパスだとimport
できる。
import
されたファイルでは、
- 実行ディレクトリと同じディレクトリ(=実行ファイルと同じディレクトリ)の場合、実行ディレクトリからのパスで
import
文を記述できる - サブディレクトリの場合、実行ディレクトリからのパスまたは、対象ファイルからの相対パスで
import
文を記述できる
結論
uvicorn
実行時はサブディレクトリに実行ファイルを配置することで、全て相対パスでの記述が可能になる。