包 __init__.py 中导入的模块不可通过点访问

A module imported in a packages __init__.py is not dot accessible

这可能是 python 想要的行为,但我仍然觉得它令人费解 -

我有以下文件结构:

repo/
    foo/
        __init__.py
        foo/
            bar.py

其中 __init__.py 如下:

from .foo import bar

当我从 repo/ 中输入 python 解释器时,我可以像这样导入 bar

>>> from foo import bar
>>> bar
<module 'foo.foo.bar' from '.../repo/foo/foo/bar.py'>

太棒了!但是,以下内容不起作用:

>>> import foo.bar as foobar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'foo.bar'

也许我不了解python 的导入语句是如何工作的,但我非常希望能够像上面显示的那样进行导入。如果这是所需的行为,有人知道解决方法吗?也许我可以在 __init__.py?

中更改一些内容

出于命名注意事项的考虑,我还使用以下文件结构对此进行了测试:

repo/
    foo/
        __init__.py
        baz/
            bar.py

...我得到了相同的结果

我已经在 python 3.6.2 和 3.6.6 的 linux 和 macOS 上对此进行了测试。我还在 python 2.7.13 中看到了相同的行为(当然,我在较低的 foo/ 目录中添加了一个 __init__.py

如果我无法实现这种导入方式,repo/ 将不得不进行一些重构。帮我防止这个!

您要导入的模块的实际名称是foo.foo.bar__init__.py 中的 from .foo import bar 不会改变这一点。

from foo import bar 将为您提供 foo 模块对象的 bar 属性,这实际上就是您想要的模块,多亏了 __init__.py 中的那一行.不过,import foo.bar 需要一个实际的 foo.bar 模块。如果它在 sys.modules 中找不到该名称的条目,它将抛出错误。不要试图把 sys.modules 到 "fix" 弄乱;导致 .