python - 如何在包内导入模块
问题描述
文件夹结构:
foo/
bar.py
__init__.py
test.py
foo/__init__.py
有import bar
我正在test.py
跑步import foo
我如何__init__.py
导入bar.py
?
ModuleNotFoundError: No module named 'foo'
为什么 Python 不为我的包创建新范围并为导入目录创建根foo
目录?
相对路径似乎也不起作用(我收到了SyntaxError
),尽管我正在寻找一种允许绝对路径的解决方案。
import .bar
两个不可接受的答案:
我不能用
import foo.bar
。我需要这个foo
包有自己独立的层/范围,这样我就可以在我的计算机中的任何地方移动它并从任何地方导入它。这意味着根可能会改变并且import foo.bar
不会总是有效。我无法将
foo
文件夹添加到我的路径中。显然,这会使路径变得混乱,并且很容易发生名称冲突。开始的感觉会说这个包的文件应该与使用它的路径分开。
也许有一个解决方案可以将此包的目录添加到仅针对该包范围的路径中,在__init__.py
?
解决方案
根据PEP 328,import X
语法纯粹用于绝对导入;因为bar
这里不是顶级模块,所以唯一有效的import X
语法是import foo.bar
.
bar
从foo
's导入的正确方法__init__.py
是:
from . import bar
您关于想要“绝对路径”的观点,但也想要类似的东西import .bar
是不可能的;即使import .bar
有效,这显然是一个相对路径(因为它仅相对于执行它的模块才有意义;.bar
如果在foo
包之外导入则没有意义)。
至于“为什么 Python 不为我的包创建一个新的范围并将导入的根目录设置为 foo 目录?” 一个简单的例子是想象你的子模块被命名math
,而不是bar
。有什么作用:
import math
在这种情况下是什么意思?如果这意味着您的子模块,您如何获得内置的顶级math
模块?这些问题(我在 Python 2 代码中遇到的问题是我未能 include 时遇到的from __future__ import absolute_import
)是存在 PEP 328 和默认绝对导入的原因;一种语法始终是绝对的(消除歧义),您可以在需要时使用相对导入语法来执行相对导入(也没有歧义)。
推荐阅读
- hyperledger-fabric - configtxgen 失败:ERRO 003 找不到配置文件
- ruby - duckduckgo.com 获取指定短语的前 N 个结果,使用 Net::HTTP ruby
- java - Neo4j 的 Spring Date 存储库和“isEmpty”查询抛出“IllegalArgumentException”
- mysql - MySQL的复杂排序
- python-3.x - ValueError:使用 tf.saved_model.load 导入 SavedModel 需要“tags=”参数
- web-scraping - 我该如何解决这个问题,它不返回文本?
- sql - 如何从一个复杂的查询中创建一个表并通过不断的更新来获得它?
- java - android中的乘法持久性程序
- python - 如何编写与此邮递员请求执行相同操作的 python 脚本
- windows - 用于更新 Windows Server 故障转移群集中群集 IP 资源名称的 Powershell 命令