5.4.2. 子模块

当使用任意机制 (例如 importlib API, importimport-from 语句或者内置的 __import__()) 加载一个子模块时,父模块的命名空间中会添加一个对子模块对象的绑定。 例如,如果包 spam 有一个子模块 foo,则在导入 spam.foo 之后,spam 将具有一个 绑定到相应子模块的 foo 属性。 假如现在有如下的目录结构:

  1. spam/
  2. __init__.py
  3. foo.py
  4. bar.py

并且 spam/__init__.py 中有如下几行内容:

  1. from .foo import Foo
  2. from .bar import Bar

则执行如下代码将在 spam 模块中添加对 foobar 的名称绑定:

  1. >>> import spam
  2. >>> spam.foo
  3. <module 'spam.foo' from '/tmp/imports/spam/foo.py'>
  4. >>> spam.bar
  5. <module 'spam.bar' from '/tmp/imports/spam/bar.py'>

按照通常的 Python 名称绑定规则,这看起来可能会令人惊讶,但它实际上是导入系统的一个基本特性。 保持不变的一点是如果你有 sys.modules['spam']sys.modules['spam.foo'] (例如在上述导入之后就是如此),则后者必须显示为前者的 foo 属性。