我正在尝试使用IBM的Qiskit,它是用于量子计算电路设计和仿真的Python库。
尤其是,我需要使用子模块qiskit.aqua.components.oracle
,它是qiskit.aqua.components
的子模块。但是,当我尝试
import qiskit.aqua.components
qiskit.aqua.components
中只有部分而非全部子模块被导入。
我必须手动导入qiskit.aqua.components.oracle
。
如果快速浏览一下源代码(https://github.com/Qiskit/qiskit-aqua/tree/master/qiskit/aqua),则看不到任何特殊原因。有人可以帮我吗?
答案 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
)。