Pythonのmoduleとpackage

python

Python ではファイルがそのまま module となる。 module をコンパイルした pyc ファイルは py_cache にキャッシュされ、ソースの変更日時を見て再利用される。

6. モジュール — Python 3.9.1 ドキュメント

モジュール名はグローバル変数 name に入り、エントリーポイントではこれが main となるので、 if name == “main”: のようにすると import した場合は実行されないようにできる。

from module import * で import すると関数外のコードは実行されず、_ から始まる関数は import されない。

$ cat foo.py
def bar():
  print("hello")

def _bar():
  print("world")

print("aaaa")

$ python
...
>>> import foo as f
aaaa
>>> f.__name__
foo
>>> f.bar()
hello
>>> f._bar()
world

>>> from foo import *
>>> bar()
hello
>>> _bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name '_bar' is not defined

>>> from foo import _bar
>>> _bar()
world

ディレクトリは pacakge となり、ディレクトリ名の名前空間が作られる。

$ tree hoge/
hoge/
└── fuga.py

$ cat hoge/fuga.py 
def piyo():
  print("ok")

$ python
>>> import hoge.fuga
>>> hoge.fuga.piyo()
ok

しかし from package import * してもその submodule である fuga が import されたりはしない。

>>> from hoge import *
>>> fuga.piyo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'hoge' has no attribute 'fuga'

package の中に init.py というファイルを作ると、その package や submodule がimportされた際にまず import される。 ここにグローバル変数 all を定義すると from package import * したときにそれらが import されるようになる。

$ cat hoge/__init__.py 
__all__ = ["fuga"]
print("aaaaa")

>>> from hoge import *
aaaaa
>>> fuga.piyo()
ok

package の他の submodule を import するような場合は、 import foo.bbb のように絶対 import するほかに、次のように相対 import することもできる。 相対 import はそのモジュール名をベースとするので、main となるメインモジュールでは使えない。

$ tree foo
foo
├── aaa.py
└── bbb.py

$ cat foo/aaa.py
from .bbb import *