我创建了一个简单的包来说明这个问题。这是文件结构:
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
文件的人,请注意这不是问题。
答案 0 :(得分:2)
问题是__main__.py
被视为脚本而不是pypkg
模块的一部分。从__main__.py
的角度来看,sub_a
和sub_b
被视为两个不共享父模块的模块。如果您将布局更改为
pypkg
├── __main__.py
└── pkg
├── __init__.py
├── sub_a
│ └── __init__.py
└── sub_b
└── __init__.py
即使从sub_a
调用, sub_b
和pkg
也会共享公共父模块__main__.py
。这允许您在sub_b/__init__.py
中执行相对导入:
from ..sub_a import foo
在Python 2下,您可能需要添加行
from __future__ import absolute_import
答案 1 :(得分:0)
python根据你的工作路径计算路径。
因此,您可以选择使用具有固定工作路径的绝对模块路径还是使用具有可变工作路径的相对模块路径。