为什么某些Python子模块无法自动导入?

时间:2020-03-17 03:48:39

标签: python import

我正在尝试使用IBM的Qiskit,它是用于量子计算电路设计和仿真的Python库。

尤其是,我需要使用子模块qiskit.aqua.components.oracle,它是qiskit.aqua.components的子模块。但是,当我尝试

import qiskit.aqua.components

qiskit.aqua.components中只有部分而非全部子模块被导入。 enter image description here 我必须手动导入qiskit.aqua.components.oracleenter image description here 如果快速浏览一下源代码(https://github.com/Qiskit/qiskit-aqua/tree/master/qiskit/aqua),则看不到任何特殊原因。有人可以帮我吗?

1 个答案:

答案 0 :(得分:0)

当你导入一个(子)模块时,模块本身决定它公开哪些成员。不会自动包含更多子模块。在您的情况下,您导入 qiskit.aqua.components 并且 components 模块通过其 __init__.py 决定它公开的成员。下面是一个示例结构:

qiskit/
├── aqua
│   ├── components
│   │   ├── __init__.py
│   │   └── oracles
│   │       └── __init__.py
│   └── __init__.py
└── __init__.py

__init__.py 文件定义了每个(子)模块的内容。在上面的例子中,它们都是空的。所以让我们导入 qiskit.aqua.components 并检查模块:

>>> import qiskit.aqua.components
>>> qiskit.aqua.components
<module 'qiskit.aqua.components' from '/tmp/qiskit/aqua/components/__init__.py'>
>>> dir(qiskit.aqua.components)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
>>> qiskit.aqua.components.oracles
...
AttributeError: module 'qiskit.aqua.components' has no attribute 'oracles'

由于 components/__init__.py 没有选择公开其子模块,因此无法从该模块内部访问它们。我们可以通过将 from . import oracles 添加到 components/__init__.py 来改变它:

$ cat qiskit/aqua/components/__init__.py 
from . import oracles

现在让我们再次导入模块(由于 module caching,需要重新启动 Python REPL):

>>> import qiskit.aqua.components
>>> dir(qiskit.aqua.components)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'oracles']
>>> qiskit.aqua.components.oracles
<module 'qiskit.aqua.components.oracles' from '/tmp/qiskit/aqua/components/oracles/__init__.py'>

如我们所见,现在可以访问 oracles 模块。

对于您的具体示例,qiskit/aqua/components/__init__.py 文件不会导入 oracles 子模块,因此您需要单独导入它才能访问它。


关于 import x.y.z 的注释:首先导入 x,然后是 x.y,最后是 x.y.z,使这些模块可用。但它停在那里并且不会在模块嵌套中更深入,因此需要手动导入任何其他子模块(例如 import x.y.z.foo)。