pythonの自作クラスや自作モジュールのパス設定について
pythonのパス設定は少し特殊で、これまでエンジニアとしてjava等で開発を行ってきた人には多少違和感があると思いましたのでメモを残したいと思います。
例えば以下のような構成でpythonのコードを組んだとします。
main.py
folder/a.py
folder/subfolder/b.py
コードの内容としては、main.pyが、一つ下の階層にあるa.pyモジュールのaクラスをimportして、aクラスのaメソッドを呼ぶ。(メイン処理)
a.pyのaクラスは、一つ下の階層にあるb.pyモジュールのbクラスをimportして、bクラスのbメソッドを呼ぶ。
上記構成で、main.pyを実行するパスの問題でエラーになります。
*a.pyで読み込んでいるsubfolderが見つからないと言われます。
これは、pythonのimportの仕組みによるものが原因で、恐らくpythonは単純にimoprtされたファイルを読み込んでいるだけだと思われます。
その為、main.pyを実行した場合の挙動は以下のようになると思われます。
main.py
この際、実行されたmain.pyはルートフォルダにいるので、そこからsubfolderが見つからない為、エラーになっています。
(ルートフォルダの直下にはfolderしかないので、当然と言えば当然になります。)
解決策として私が対応したのは以下の2パターンです。
sys.path.appendでパスを追加する
.pthファイルでパス問題を追加する
1.sys.path.appendでパスを追加する方法
main.pyの実行時にsubfolderが見つからないと怒られているので、folderにパスをsys.path.appendで追加する。
main.py
これで、folderにもパスが通る為、subfolderもmain.pyから見れるようになります。
2.pthファイルでパスを追加する
pythonのsite-packagesフォルダに.pthファイルを配置する。
例えば、.pthファイルを、mypath.pthとした場合、mypath.pthファイルにfolderのパスを記載して、pythonのsite-packagesフォルダに配置する。
mypath.pth
*pythonのsite-packagesフォルダのパスは、以下のコマンドを実行すると確認できます。
python -c "import site; print (site.getsitepackages())"
補足:上記以外にもPoetryを使用した方法がありますので、興味がある方は以下を参照してください。
(https://qiita.com/siida36/items/b171922546e65b868679)
まとめ
pythonの自作モジュールや自作クラスにパスを通す方法としては、私個人としては、2.の.pthファイルの対応を採用しています。
但し、上記2. の手順とは若干パスの通し方を変えていまして、folderではなく、ルートフォルダにパスを通しています。
mypath.pth
こうした場合、a.pyのソースファイルは次のようになります。
folder/a.py
必ず、imoprtする際は、ルートフォルダからのパスを指定する形になります。
これの何がメリットかというと、subfolderの下にsubsubfolderを作成して、c.pyというファイルを配置し、b.pyから、c.pyをimportする場合も同じようにルートフォルダからのパスの指定で対応ができます。
folder/subfolder/b.py
*前述の通り、必ずルートフォルダからimportする形式になり、ソース全体としてimportの記述が統一されます。
従来の方法だと.pthファイルにsubfolderのパスも追加する必要が出てきます。
mypath.pth
システムが大きくなるにつれて、フォルダは拡張及び細分化していきますのでその都度上記パスファイルを弄るのは非常に面倒ですし、管理が煩雑になります。
最後に1.sys.path.appendの方法については、個人的にはお勧めしません。
理由としては、システムの規模が大きくなるにつれて、sys.path.appendがいろいろなソースコードに埋め込まれて、パスの管理が困難になるからです。
こうなってくると、importの順番で偶然パスが通る場合と、通らない場合が発生したりしてデバッグが大変になります。
また、ネットで調べたところsys.path.appendはコーディング規約違反らしいので、何れにせよ使わない方が良いのかもしれません。
■参考資料
sys.path.appendはコーディング規約違反(https://qiita.com/siida36/items/b171922546e65b868679)
この記事が気に入ったらサポートをしてみませんか?