【发布时间】:2012-06-07 23:44:25
【问题描述】:
这是一个 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 在bar 完全加载之前执行,因此它无法导入模块(也来自bar)它包含自己的基类。我来自 C++ 世界,超嵌套的命名空间不是完整的,简单的前向声明可以解决这个问题,但我被引导相信我正在寻找的东西是可能的,至少是一个有点可接受的 Pythonic 解决方案。我究竟做错了什么?使子模块中的类在父模块的命名空间中可用的正确方法是什么?
【问题讨论】:
标签: python import module namespaces package