从外部

时间:2017-05-09 12:49:12

标签: python python-import python-packaging

我创建了一个简单的包来说明这个问题。这是文件结构:

pypkg
├── __init__.py
├── __main__.py
├── sub_a
│   └── __init__.py
└── sub_b
    └── __init__.py

sub_a有一个函数foo

# sub_a/__init__.py
def foo():
    print 'foo'

sub_b有一个函数foobar,可以调用foo

# sub_b/__init__.py
from sub_a import foo

def foobar():
    foo()
    print 'bar'

在主文件中,我导入foobar没有问题:

# __main__.py
from sub_b import foobar

if __name__ == '__main__':
    foobar()

如果我使用python pypkg运行包,它就可以了。当我尝试从外部使用foobar时,问题就出现了。我在路径中添加了pypkg但是当我尝试导入foobar时,它会引发ImportError异常。这是一个演示:

In [1]: from pypkg.sub_b import foobar
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-37682ecaec63> in <module>()
----> 1 from pypkg.sub_b import foobar

[...]/pypkg/sub_b/__init__.py in <module>()
----> 1 from sub_a import foo
      2 
      3 def foobar():
      4         foo()
      5         print 'bar'

ImportError: No module named sub_a

发生ImportError并不是因为它找不到sub_b - 它可以 - 问题发生是因为包无法导入自己的“邻居子包”。这带来了一个问题:如何从外部正确导入foobar

我对这个主题进行了广泛的研究,关于SO的绝大多数问题是没有放置__init__.py文件的人,请注意这不是问题。

2 个答案:

答案 0 :(得分:2)

问题是__main__.py被视为脚本而不是pypkg模块的一部分。从__main__.py的角度来看,sub_asub_b被视为两个不共享父模块的模块。如果您将布局更改为

pypkg
├── __main__.py
└── pkg
    ├── __init__.py
    ├── sub_a
    │   └── __init__.py
    └── sub_b
        └── __init__.py
即使从sub_a调用,

sub_bpkg也会共享公共父模块__main__.py。这允许您在sub_b/__init__.py中执行相对导入:

from ..sub_a import foo

在Python 2下,您可能需要添加行

from __future__ import absolute_import

答案 1 :(得分:0)

python根据你的工作路径计算路径。

因此,您可以选择使用具有固定工作路径的绝对模块路径还是使用具有可变工作路径的相对模块路径。