python - 在包 __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/
将不得不进行一些重构。帮我防止这种情况!
解决方案
您要导入的模块的实际名称是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
“解决”这个问题;这会导致真正令人困惑的双重导入错误。
推荐阅读
- c++ - 由于内存映射,无法处理视频或 Videopath
- python - 基于Django函数的视图分页不起作用
- angular - 在 nz-row 和 nz-col 上构建和服务失败
- android - telnet 可以用来在通过 USB 连接的真实 android 设备上设置 gps 位置吗?
- javascript - 如何检查是否仅使用 JavaScript 选择了单选按钮?
- javascript - 如何处理网络浏览器中弹出的身份验证
- java - ListSelectionListener 在调用 setSelected 方法时不会触发事件
- javascript - X 轴上的 Charts.js + Django 日期
- mysql - 选择 table1 中的所有行,以及 table2 中不在表 1 中的行
- c# - 不适用于嵌套子级的 AutoMapper IncludeMembers