导入软件包时出现Python导入错误

时间:2019-07-18 09:08:27

标签: python python-3.x python-import

我对python导入有一个奇怪的(对我来说)问题,我想了解它的问题所在。

我创建了一个具有以下目录结构的演示项目:

├── entry.py
└── foo
    ├── __init__.py
    └── bar
        ├── __init__.py
        ├── sdk.py
        ├── service.py
        └── utils.py

如果我运行python entry.py,则在service.py中,以下语句有效:

from foo.bar import utils

这不是:

import foo.bar.utils as utils
# entry.py:

from foo.bar.sdk import get_sdk
print(get_sdk())

# foo - __init__.py
# empty on purpose

# bar - __init__.py
from .service import Service

# sdk.py
def get_sdk():
    return "SDK"

# service.py
import foo.bar.utils as utils # wrong import
# from foo.bar import utils # works!
class Service:
    def do_service(self):
        util = utils.get_utility_string()
        print("Doing service call {}".format(util))

# utils.py
def get_utility_string():
    return "This is useful"

通过运行python entry.py我得到:

Traceback (most recent call last):
  File "entry.py", line 1, in <module>
    from foo.bar.sdk import get_sdk
  File "/Users/paloand/Downloads/p_demo/foo/bar/__init__.py", line 1, in <module>
    from .service import Service
  File "/Users/paloand/Downloads/p_demo/foo/bar/service.py", line 1, in <module>
    import foo.bar.utils as utils
AttributeError: module 'foo' has no attribute 'bar'

据我在entry.py中的理解,当get_sdk模块中出现sdk符号时,也正在导入foo包。在foo中导入bar时,__init__.py文件请求导入Service符号。因此,在导入foo时,service.py中再次需要它。

在我的Dropbox中链接到上载的演示项目:Demo

我已经阅读了this个问题和所有答案,但是在那里我无法提取任何信息。我也找到了这个bug,但不确定在这里是否适用。我还阅读了python中的common traps导入,但找不到此。

我想了解两者之间的差异以及实际发生的情况。

我正在使用 python 3.6

谢谢

编辑

已更新,并显示错误消息

编辑2

在两种情况下,我都尝试过python -vv entry.py。相关日志位于粘贴中:https://pastebin.com/J9guMqJS

在两种情况下,导入顺序都相同,在“不良”情况下,此导入失败:

import 'foo.bar.utils' # <_frozen_importlib_external.SourceFileLoader object at 0x1103ddf28>

0 个答案:

没有答案