在 Python 和 __init__.py 中导入模块

Posted

技术标签:

【中文标题】在 Python 和 __init__.py 中导入模块【英文标题】:Importing modules in Python and __init__.py 【发布时间】:2011-05-06 10:58:20 【问题描述】:

我一直在阅读__init__.py 文件的功能。据说我们需要在包含模块的文件夹中创建一个空的__init__.py文件,以便导入这些模块。但是,我尝试将文件夹路径添加到 PYTHONPATH(Windows 7 中的环境变量)。尽管此文件夹不包含 __init__.py 文件,但我仍然可以从该文件夹导入模块。您能否解释一下如何在不存在__init__.py 的情况下导入这些模块?

谢谢,

最好的问候

【问题讨论】:

【参考方案1】:

__init__.py 将文件夹转换为package。这对于创建一种模块层次结构很有用,您可以在其中拥有如下导入语句:

import mymodule.cool.stuff

如果没有包,这是不可能的。

【讨论】:

好的,假设有一个文件夹:“A”。 “A”有一个__init__.py。但是“A”不在 PYTHONPATH 中。我可以从“A”文件夹导入模块吗? Python 是否会搜索我计算机中的所有文件夹以了解其中是否包含“__init__.py”?我的意思是python如何知道“A”的路径? @steve:您仍然需要将包的路径添加到您的PYTHONPATH。 Python 不会在整个计算机中搜索包含 __init__.py 的文件夹。【参考方案2】:

如果一个目录(文件夹)包含一个__init__.py 文件,那么它就成为一个。正如您发现的那样,您认为自己阅读的内容并不完全正确。一个包可以像一个模块一样被导入,__init__.py 中的任何代码都会运行,尽管它通常是空的。包是将多个模块组合在一起的一种方式,您可以使用以下方式加载它们:

import package-name.module-name

包也可以嵌套,而且经常如此。在 Python 软件目录下的 Lib 目录中查找许多示例。

【讨论】:

【参考方案3】:

在你的模块目录中有_init_.py没有的区别是:

当你 __init__.py(空白之一)时,你可以使用

导入模块
from dirname import MyModule

但是当你没有 _init_.py 时,如果不将该模块的路径添加到 PYTHONPATH,则无法导入该模块。 在这种情况下 from dirname import MyModule 失败,或者报告错误。

# 没有_init_.py的目录/模块结构

[root@Machine python]# cd NoInitModule/
[root@Machine NoInitModule]# pwd
/python/NoInitModule
[root@Machine NoInitModule]# ls -l
total 4
-rw-r--r--. 1 root root 44 Jan 16 07:02 ModuleX.py

# _init_.py

的目录/模块结构
[root@Machine NoInitModule]# cd ../InitModule/
[root@Machine InitModule]# ls -l
total 4
-rw-r--r--. 1 root root  0 Jan 16 07:13 __init__.py
-rw-r--r--. 1 root root 49 Jan 16 07:12 ModuleY.py
[root@Machine InitModule]#

示例:

# NO _init_.py, from dir import module statement - DOESN'T WORK

[root@Machine python]# cat impomod.py
from NoInitModule import ModuleX

ModuleX.printBye()

[root@Machine python]# python impomod.py
Traceback (most recent call last):
  File "impomod.py", line 7, in <module>
    from NoInitModule import ModuleX
ImportError: No module named NoInitModule
[root@Machine python]#

# NO _init_.py,导入语句 - 不起作用

[root@Machine python]# vim impomod.py
[root@Machine python]# cat impomod.py
#from NoInitModule import ModuleX
import ModuleX

ModuleX.printBye()
[root@Machine python]# python impomod.py
Traceback (most recent call last):
  File "impomod.py", line 8, in <module>
    import ModuleX
ImportError: No module named ModuleX
[root@Machine python]#

# NO _init_.py, INSERT path in PYTHONPATH, import module statement after insert path - WORKS

[root@Machine python]# vim impomod.py
[root@Machine python]# cat impomod.py
import sys
sys.path.append('/python/NoInitModule')
print sys.path

import ModuleX
ModuleX.printBye()

[root@Machine python]# python impomod.py
Bye from Module X with no __init__.py
[root@Machine python]#

# HAVING _init_.py,没有 INSERT of path,from dir import module 语句 - WORKS

[root@Machine python]# cat impXmod.py
import sys
from InitModule import ModuleY
ModuleY.printSeeU()
[root@Machine python]#

[root@Machine python]# python impXmod.py
See you from Module Y having __init__.py

# HAVING _init_.py,没有插入路径,导入模块语句 - 不起作用

[root@Machine python]# vim impXmod.py
[root@Machine python]# cat impXmod.py
import sys
#from InitModule import ModuleY
import ModuleY
ModuleY.printSeeU()

[root@Machine python]# python impXmod.py
Traceback (most recent call last):
  File "impXmod.py", line 3, in <module>
    import ModuleY
ImportError: No module named ModuleY

当然,子文件夹问题可以添加到这里

【讨论】:

【参考方案4】:

是的,如您所知,这很有效。 __init__.py 文件为空的原因是将 子文件夹 标记为包含模块的文件夹。

因此,PYTHONPATH 中的文件夹可以在其中包含模块,但这些文件夹的任何子文件夹中都必须包含 __init__.py 文件才能从中导入模块。

【讨论】:

__init__.py 没有为空。 @Ignacio:如果它的唯一任务是将文件夹标记为具有模块,它也不必在其中包含某些内容。 OP 提到了空的__init__.py 文件。

以上是关于在 Python 和 __init__.py 中导入模块的主要内容,如果未能解决你的问题,请参考以下文章

Python 从更高级别的包中导入模块

使另一个模块可以从我的 Python 模块中导入

如何使用 importlib.import_module 在 Python 中导入模块

[Python] 关于__init__.py

在 python3 中导入超出***包失败

python - 在同一目录中导入模块[重复]