首页 > 解决方案 > 在包 __init__.py 中导入的模块不可访问

问题描述

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

我有以下文件结构:

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

以下内容在哪里__init__.py

from .foo import bar

当我从内部输入 python 解释器时repo/,我可以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 的 import 语句的工作原理缺乏了解,但我非常希望能够像上面显示的那样导入。如果这是所需的行为,是否有人知道解决方法?也许我可以改变一些东西__init__.py

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

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

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

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

如果我无法使这种风格的导入工作,repo/将不得不进行一些重构。帮我防止这种情况!

标签: pythonpython-3.xpython-import

解决方案


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

from foo import bar将为您提供模块对象的bar属性foo,这实际上是您想要的模块,这要归功于__init__.py. import foo.bar不过,需要一个实际的foo.bar模块。如果它在 中找不到该名称的条目sys.modules,它将引发错误。不要试图去sys.modules“解决”这个问题;这会导致真正令人困惑的双重导入错误


推荐阅读