这是一个python模块。foo
在sys.path
.
foo\
__init__.py
bar\
__init__.py
base.py
class Base(object)
derived.py
import foo.bar.base as base
class Derived(base.Base)
我还没有什么特别的事情发生。如果我想从模块中实例化Derived类derived
,我可以很容易地做到这一点:
import foo.bar.derived as derived
print(derived.Derived())
但是,我只想导入bar
模块并调用bar.Derived()
,因为我计划在许多不同的模块中包含许多类,并且我不想处理所有这些触手可及的导入路径。我的理解是,我可以简单地将Derived导入模块的命名空间,方法是bar
像这样修改我的项目:
foo\
__init__.py
bar\
__init__.py
from foo.bar.derived import Derived
base.py
class Base(object)
derived.py
import foo.bar.base as base
class Derived(base.Base)
现在我应该能够做到以下几点:
import foo.bar as bar
print(bar.Derived())
但是我收到一个 AttributeError 抱怨该foo
模块没有名为的子模块bar
:
test.py (1): import foo.bar
foo\bar\__init__.py (1): from foo.bar.derived import Derived
foo\bar\derived.py (1): import foo.bar.base as base
AttributeError: 'module' object has no attribute 'bar'
事实上,我的原始测试代码(在顶部)也不起作用!一旦我尝试导入foo.bar
,我就会收到错误。
我可以从这个错误中看到的是,在__init__.py
导致derived.py
之前执行的 import 语句bar
已完全加载,因此它无法导入bar
包含其自己的基类的模块(也 from )。我来自 C++ 世界,超嵌套的命名空间不是完整的,简单的前向声明可以解决这个问题,但我被引导相信我正在寻找的东西是可能的,至少是一个在某种程度上可以接受的 Pythonic 解决方案。我究竟做错了什么?使子模块中的类在父模块的命名空间中可用的正确方法是什么?