似乎我还缺少一些python的基础知识。我试图理解submodules importing,但我觉得我还没有理解。但我也发现了一些新的东西。你知道吗
我在两个不同的PyDev项目中拥有以下两个包:
package1
|
+--mod1.py
|
+--mod2.py
package2
|
+--__init__.py
|
+--modx.py
|
+--mody.py
在mod1
,我可以做import mod2
。但是在__init__
和modx
中,我不能执行import mody
(Eclipse称为“未解析的导入”)。在__init__
中,我可以做import .mody
或from .mody import vary
。在modx
中,我不能做import .mody
。(事实上,我从未见过在import
语句中使用.
作为模块的前缀。之前我只见过import mod
和from mod import var
,但从未见过import .mod
和from .mod import var
为什么会发生这种情况?我一定不知道是什么原因导致了这种行为。但我不知道是什么?你知道吗
PS:我正在使用Python3.4
Python处理这两个包的方式有细微的不同。你知道吗
package1
被视为命名空间包,因为它不包含__init__.py
文件。你知道吗package2
被视为常规的包,因为它不包含__init__.py
文件。你知道吗因此,我将快速分析每一步发生的原因:
这是由于命名空间使用绝对导入处理包的方式造成的。您很可能是从存储文件的目录执行
python mod1.py
,对吧(在我尝试重新创建您的文件夹结构并在本地测试它时,我也是这么做的)?因此package1
成为当前工作目录,而mod2
文件位于该目录的根目录。你知道吗对于名称空间包,Python将默认地查找
sys.path
,试图找到您请求的导入。由于您当前的工作目录会自动添加到sys.path
并包含在其中,因此Python可以毫无困难地成功地找到您的import mod2
请求。你知道吗感谢ShadowRanger纠正了我最初的回答,我误解了Python是如何在搜索中包含当前工作目录的。
这是因为Python将其视为常规的包。在本例中,常规包的名称是
package2
。当您使用.
表示法时,您要求Python开始从当前的包(在本例中是您的父package2
)中搜索导入。因此必须使用import .mody
在当前包中查找mody
包。你知道吗如果您使用
..
,那么它将从当前包的父级导入,依此类推。你知道吗当您显式声明只希望从当前包中搜索时,点表示法非常有用—因此,如果在您的
PYTHONPATH
上有另一个package2
包,Python将知道要选择哪一个。你知道吗对于
__init__.py
,这是因为您没有使用点表示法,也没有告诉Python您希望在当前的包中搜索这些模块。因此,它在Python标准库和PYTHONPATH
中寻找这些包,却没有找到它们(因此在Eclipse中出现了错误)。通过使用点表示法,您表示希望在搜索中包含当前包,因此Python将能够找到这些文件。你知道吗使用这样的点表示法,通过
from . import mody
导入就是使用相对导入。你知道吗对于
modx
,还必须使用相对导入(请参阅下一节)。你知道吗这是因为您没有使用相对/绝对导入。在这种情况下,您将使用相对导入。相对导入是您已经看到的
from . import mody
语法。Python默认使用相对或绝对导入行为。你知道吗它现在是默认行为,因为对于旧的Python
import
行为,假设Python自己的标准库有一个名为mody
的包。当您使用import mody
时,它以前会从包中导入mody
,而不是标准库。这并不总是可取的。如果您特别想要标准库版本呢?你知道吗因此,现在必须使用
from . import mody
或from .mody import vary
语法进行导入,以便导入非常清楚。如果使用import
而不是from...
语法,Python将假定它是标准库或PYTHONPATH
导入。你知道吗顺便说一句,上面的很多信息来源于以下网站:
https://docs.python.org/3/reference/import.html
https://docs.python.org/2.5/whatsnew/pep-328.html
Python模块是Python的可选“添加”,可以使用
import
命令导入,如下所示:要导入包的各个部分,请使用
from
,如下所示:如果要导入模块的每个部分并在不使用
package.
的情况下使用它,请使用: 从包装1 i相关问题 更多 >
编程相关推荐