理解在python中导入模块

理解在python中导入模块,python,Python,我似乎仍然缺少python的一些基础知识。我试图理解,我觉得我还没有理解。但我也偶然发现了一些新的东西 我在两个不同的PyDev项目中拥有以下两个包: package1 | +--mod1.py | +--mod2.py package2 | +--__init__.py | +--modx.py | +--mody.py 在mod1中,我可以执行导入mod2。但是在\uuuu init\uuuu和modx中,我不能导入mody(Eclipse称为“未解析的导入”)。在\uuuu init

我似乎仍然缺少python的一些基础知识。我试图理解,我觉得我还没有理解。但我也偶然发现了一些新的东西

我在两个不同的PyDev项目中拥有以下两个包:

package1
|
+--mod1.py
|
+--mod2.py


package2
|
+--__init__.py
|
+--modx.py
|
+--mody.py
mod1
中,我可以执行
导入mod2
。但是在
\uuuu init\uuuu
modx
中,我不能
导入mody
(Eclipse称为“未解析的导入”)。在
\uuuu init\uuuu
中,我可以执行
导入.mody
from.mody导入vary
。在
modx
中,我无法执行
import.mody
。(事实上,我从未见过在
import
语句中使用
作为模块的前缀。之前我只见过
import mod
来自mod import var
,但从未见过
import.mod
来自.mod import var
)为什么会发生这种情况?我一定不知道是什么原因导致了这种行为。但是我不知道那是什么


PS:我使用的是Python 3.4

Python模块是Python的可选“添加”,可以使用
import
命令导入,如下所示:

import package1
package1.mod1   # Can be accessed using this
要导入软件包的各个部分,请使用
from
如下所示:

from package1 import mod1
mod1                      # Can be accessed using this
如果要导入模块的每个部分并在不使用
软件包的情况下使用它。
,请使用:
从package1 i

Python模块是Python的可选“添加”,可以使用
import
命令导入,如下所示:

import package1
package1.mod1   # Can be accessed using this
要导入软件包的各个部分,请使用
from
如下所示:

from package1 import mod1
mod1                      # Can be accessed using this
如果要导入模块的每个部分并在不使用
软件包的情况下使用它。
,请使用:
从package1i

来看,Python处理这两个包的方式有细微的不同

package1
被视为命名空间包,因为它不包含
\uuuu init\uuuuuuu.py
文件

package2
被视为一个常规的包,因为它不包含一个
\uuuu init\uuuuu.py
文件

因此,我将快速分析每一步发生的原因:

在mod1中,我可以导入mod2

这是由于使用绝对导入处理命名空间包的方式造成的。您很可能正在从存储文件的目录执行
python mod1.py
,对吗(在我尝试重新创建文件夹结构并在本地测试它时,我也这样做了)?因此,
package1
成为您的当前工作目录,而您的
mod2
文件位于该目录的根目录

对于名称空间包,Python将默认查找
sys.path
,试图找到您请求的导入。由于您当前的工作目录会自动添加到并包含在
sys.path
中,因此Python可以毫无困难地成功找到您的
import mod2
请求

感谢ShadowRanger纠正了我最初对这一问题的回答,我误解了Python是如何在搜索中包含当前工作目录的。

init中,我可以执行import.mody或from.mody导入

这是因为Python将其视为一个常规的包。在本例中,常规软件包的名称为
package2
。当您使用
表示法时,您要求Python开始从当前的包(在本例中是您的父
包2
)中搜索导入。因此,您必须使用
import.mody
在当前包中查找
mody

如果使用
,则它将从当前包的父级导入,依此类推

点表示法非常有用,因为您明确声明只希望从当前包中搜索-因此,如果在
PYTHONPATH
上有另一个
package2
包,Python将知道选择哪个包

但是在init和modx中,我不能导入mody(Eclipse称为“未解析的导入”)

使用
\uuuu init\uuuuu.py
这是因为您没有使用点表示法,也没有告诉Python您希望在当前的包中搜索这些模块。因此,它在寻找Python标准库和您的
PYTHONPATH
来查找这些包,但没有找到它们(因此您在Eclipse中出现了错误)。通过使用点表示法,您表示希望在搜索中包含当前包,因此Python将能够找到这些文件

使用像这样的点符号,通过
从导入。导入mody
,是使用相对导入

使用
modx
还必须使用相对导入(请参见下一节)

在modx中,我不能进行导入。为什么会发生这种情况

这是因为您没有使用相对/绝对导入。在这种情况下,您将使用相对导入。相对导入是来自的
。导入mody
您已经看到的语法。Python默认使用相对或绝对导入行为

它现在是默认行为,因为对于旧的Python
import
行为,假设Python自己的标准库有一个名为
mody
的包。当您使用
import mody
时,它以前会从包中导入
mody
,而不是标准库。这并不总是可取的。如果您特别想要标准库版本呢

因此,现在必须使用来自的
进行导入。导入mody
from。mody导入的语法不同,因此导入非常清晰。如果使用
import
而不是
from…
语法,Python将假定它是一个标准