2012-04-26 44 views
2

Python的导入功能有时候还会让我感到困惑。这里有一个例子:Python包和导入 - 需要说明

我的项目有以下封装结构:

Project/ 
    src/ 
     example/ 
      __init__.py 
      an_example.py 
     top/ 
      __init__.py 
      lin/ 
       __init__.py 
       factory.py 

an_example.py,我想写

from top import lin 
if __name__ == '__main__': 
    a = lin.factory.AClass() 

然而,这种失败:

a = lin.factory.AClass() 
AttributeError: 'module' object has no attribute 'factory' 

an_example.py作品写的像这样:

from top.lin import factory 
if __name__ == '__main__': 
    a = factory.AClass() 

您能向我解释为什么写入像第一个版本的导入语句是错误的吗?我更喜欢一个完全合格的名称,如lin.factory.AClassfactory.AClass

回答

4

这是因为,除非你告诉lin__init__.py进口factory,然后factory不在lin命名空间。

E.g:

假设现有的项目结构,an_example.py包含:

from top import lin 

lin.factory.AClass() 

随着top/lin/__init__.py空白,我们得到ImportError: No module named factory

top/lin/__init__.py包含import top.lin.factory,我们得到没有错误。

当您要求使用factory.AClass()时,它的工作原理是因为它在那里定义。同样,如果您想从那里使用它,则需要在lin中定义工厂。

+1

谢谢,我不知道我必须编辑'__init __。py'嵌套包。然而,令人困惑的是,我必须在'top/lin/__ init __。py'中导入'top.lin.factory'而不是'import factory'(这不起作用)。这意味着'lin/__ init __。py'不仅需要知道'lin /'的内容,还需要知道它包含在('top')中的包,并且在移动时必须进行编辑。这不符合模块化设计原则吗? – clstaudt 2012-04-26 13:35:07

+2

@clstaudt嗯,只有当你希望能够按照你的要求使用它们。您不需*执行此操作以使用嵌套软件包。至于绝对导入名称,作为替代,您可以使用相对导入('from。import factory'')。 – 2012-04-26 13:38:53