【发布时间】:2018-09-11 20:03:23
【问题描述】:
我在以下代码中遇到了导入错误(ImportError: cannot import name 'ClassB'):
目录结构:
main.py
test_pkg/
__init__.py
a.py
b.py
main.py:
from test_pkg import ClassA, ClassB
__init__.py:
from .a import ClassA
from .b import ClassB
a.py:
from test_pkg import ClassB
class ClassA:
pass
b.py:
class ClassB:
pass
过去我通过在 a.py 中的导入中添加全名来快速“实验”修复它:
from test_pkg.b import ClassB
class ClassA:
pass
我已阅读有关进口机械的信息并根据:
此名称将用于导入搜索的各个阶段,它可能是子模块的虚线路径,例如foo.bar.baz。在这种情况下,Python 首先尝试导入 foo,然后是 foo.bar,最后是 foo.bar.baz。 link2doc
我原以为它会再次失败,因为它会在 test_pkg 导入期间尝试导入 test_pkg,但它正在工作。我的问题是为什么?
另外还有 2 个问题:
- 跨模块依赖是否合适?
- 可以在包init.py中导入模块吗?
我的分析:
根据读数,我认识到很可能是这个问题,因为关闭
__init__.py:
from .a import ClassA
from .b import ClassB
ClassA 和 ClassB 导入作为 test_pkg 导入的一部分执行,但随后在 a.py 中命中 import 语句:
a.py:
from test_pkg import ClassB
class ClassA:
pass
它失败了,因为发生了循环依赖。
但是在使用导入时可以工作:
from test_pkg.b import ClassB
根据我的理解不应该,因为:
此名称将用于导入搜索的各个阶段,它 可能是子模块的虚线路径,例如foo.bar.baz。在这种情况下, Python 首先尝试导入 foo,然后是 foo.bar,最后是 foo.bar.baz。如果任何中间导入失败,则 引发 ModuleNotFoundError。
所以我期待两个导入的行为相同。
看起来使用完整路径导入没有启动有问题的 test_pkg 导入过程
from test_pkg.b import ClassB
【问题讨论】:
-
更改了类名以使代码更清晰
标签: python