从outsid调用Python包时无法导入相邻子包

2024-04-29 07:53:27 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

sub_a有一个函数foo

^{pr2}$

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?在

我对这个话题做了广泛的研究,绝大多数问题都是关于那些没有放置__init__.py文件的人,注意到这不是这里的问题。在


Tags: 文件函数frompyimportfooinitmain
2条回答

问题是__main__.py被看作是一个脚本,而不是pypkg模块的一部分。从公共的观点来看,cd4{cd4{1}和

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

sub_asub_b将共享公共父模块pkg,即使从{}调用时也是如此。这允许您在sub_b/__init__.py中执行相对导入:

^{pr2}$

在python2下,您可能需要添加以下行

from __future__ import absolute_import

python根据您的工作路径计算路径。在

所以你可以选择使用固定工作路径的绝对模块路径还是可变工作路径的相对模块路径。在

相关问题 更多 >