awf*_*the 1 python import namespaces module package
这是一个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)
Run Code Online (Sandbox Code Playgroud)
我还没有想到什么.如果我想从模块中实例化Derived类derived,我可以很容易地做到这一点:
import foo.bar.derived as derived
print(derived.Derived())
Run Code Online (Sandbox Code Playgroud)
但是,我想导入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)
Run Code Online (Sandbox Code Playgroud)
现在我应该能够做到以下几点:
import foo.bar as bar
print(bar.Derived())
Run Code Online (Sandbox Code Playgroud)
但我得到一个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'
Run Code Online (Sandbox Code Playgroud)
事实上,我原来的测试代码(顶部)也不起作用!一旦我尝试导入foo.bar,我就会收到错误.
我可以从这个错误中发现,__init__.py导致derived.py之前执行的导入语句bar是完全加载的,因此它无法导入bar包含其自己的基类的模块(也来自).我来自C++世界,其中超嵌套的命名空间不是完整的,简单的前向声明会否定这个问题,但我一直认为我正在寻找的是可能的,至少是有点可接受的Pythonic解决方案.我究竟做错了什么?从父模块命名空间中可用的子模块创建类的正确方法是什么?
如果您使用的是Python 2.5或更高版本,请尝试使用显式相对导入(http://www.python.org/dev/peps/pep-0328/#guido-s-decision):
test.py (1): import foo.bar
foo\bar\__init__.py (1): from .derived import Derived
foo\bar\derived.py (1): from . import base
Run Code Online (Sandbox Code Playgroud)
(请注意,如果您确实使用Python 2.5或2.6,则需要包含from __future__ import absolute_import在模块中.)