
Python+Qtアプリ開発日記#3
開発環境も整って、いざ作っていくがここで色々と迷うことが出てくる。
その一つがインポート(import)。
今回はこのインポートについて悩みどころを書いていこうと思う。
まだ悩まないレベル
下は、イラストとパッケージが育って行く過程を示したもので
"house"というパッケージ(アプリ)を作って行く過程で、いくつかの処理を分けてい行くことが予想される過程をイラスト(比喩)と階層図で表現してみた。
この図では、main.pyがいわゆるmainモジュールが定義されているものとして示している。
この場合、main,pyでは、sub.py、child.pyで定義されたモジュールを使うには、以下の様に"from import"文で使えるようになる。
from child import 〇〇〇
from sub import 〇〇〇

多少、モジュールが増えたところで"from import"文が増えるだけであまり悩まない。
from child1 import 〇〇〇
from child2 import 〇〇〇
from sub import 〇〇〇
ファイルが10以下ぐらいであれば、このままでもいいけど、サブパッケージも関連するものでまとめていくと、以下のように育った場合に悩みが出てくる。以下はそこそこ育った状態。

この状態から、あるパッケージから違うパッケージのモジュールを使いたい場合になってきた時、例えば以下のような場合。

インポート文を相対パスでやっていると
attempted relative import beyond top-level package
やりがちなことであるが、は!なんでってなる。
例外のメッセージの通り、トップレベルを経由した相対インポートはできないとなる。これはそういう仕様なので仕方だ無い。

例外出ないようにするなら、以下のようにる絶対インポートで書けばいいと言うことになる。

普通なら、絶対インポートで書けば解決で終わりなんだけど、悩みどころは、更に成長していったりするとモジュールの配置が変わっていき、そのたびにインポートエラーを修正せんとあかん状態に陥る。まー修正すればいいいだけど面倒になってくる。一部をサイトパッケージにして簡略もできるけどそこまでしたいわけじゃない。webで検索すると、規模が大きいなら絶対インポートかモジュールパスを追加しろだけど、モジュールパスは余計なことになる場合があるのでそれもな~とウダウダ考えてしまうわけです。
で、自分なりの解決策は、パッケージ内に配置する"__iniit__.py"では。
相対インポートでモジュールを公開。
利用する側は、絶対インポートでパッケージ名(フォルダ)で参照する様にした。下図は、独自パッケージのコード配置。


今回はここまで。