import 時のシステムの処理
例: (a/b/c.py で a,b はパッケージ、 c はモジュール
__init__.py はなし)
import a.b.c が実行された時、
キャッシュ確認: sys.modules["a.b.c"] があればシステムはこれを返す
探索: なければ sys.path に含まれるパスを起点に a/b/c.py を探す
連鎖ロードと属性定義:
import a import a.b import a.b.c を順に実行する
この過程で、パッケージ a b のフォルダ内に __init__.py があれば
そのコードが実行され、定義されたものがそれぞれのパッケージの属性となる
また、モジュール c 内の関数などが c の属性となる
キャッシュ: sys.modules["a"], sys.modules["a.b"], sys.modules["a.b.c"] に保存する
階層構築:
a は属性として b を、 b は属性として c をセットされ、ツリー構造になる
名前の登録:
最後に、最上位のパッケージ名 a が変数として呼び出し元のスコープに登録される
利用:
この a を起点として、 a.b.c のようにサブモジュールにアクセスできるようになる
また、このインポート過程で a は属性 b をもつので a.b にもアクセスできる
しかし、 b は属性 c しかもっていないので、 同じフォルダ内にある他のモジュールにはアクセスできない
(例えば、 a/b/d.py があったとして、 a.b.d のようにアクセスすることはできない)
a のフォルダ内にある他のモジュールについても、同様の理由でアクセスできない
キャッシュ
パッケージ.モジュール 形式の名前で sys.modules に登録されたロード済みのモジュール
import 時にキャッシュがあればシステムはこれを返す